Общая стратегия обработки исключений.NET

При выполнении 'git pull' произошла та же ошибка, и вот как я это исправил.

  1. Изменить репо на HTTPS
  2. Команда запуска git config --system --unset credential.helper
  3. Команда запуска git config --system --add credential.helper manager
  4. Команда тестирования git pull
  5. Ввод всплывающие учетные данные в окне входа в систему.
  6. Git pull успешно завершен.
12
задан John Saunders 26 June 2009 в 18:11
поделиться

11 ответов

Нет, не лови все. Исключения распространяются выше в стеке. Все, что вам нужно сделать, это убедиться, что исключение было перехвачено до того, как оно попадет в верхнюю часть стека.

Это означает, например, что вы должны окружить код обработчика события блоком try / catch. Обработчик событий может быть «вершиной стека». То же самое для обработчика ThreadStart или обратного вызова из асинхронного метода.

Вы также хотите перехватывать исключения на границах уровня, хотя в этом случае вы можете просто заключить исключение в исключение для конкретного уровня.

В В случае с ASP.NET вы можете разрешить ASP.NET Health Monitoring регистрировать исключение за вас.

Но вам, конечно, никогда не нужно перехватывать исключения в каждом методе. Это главный антипаттерн.

18
ответ дан 2 December 2019 в 04:09
поделиться

I don't think you need to catch everything at the point of infraction. You can bubble up your exceptions, and then use the StackTrace to figure out where the point of infraction actually occurred.

Also, if you need to have a try catch block, the best approach I've heard is to isolate it in a method, as to not clutter the code with huge try catch blocks. Also, make as few statements as possible in the try statement.

Of course, just to reiterate, bubbling up your exceptions to the top and logging the stacktrace is a better approach than nesting try-catch-log-throw blocks all throughout your code.

1
ответ дан 2 December 2019 в 04:09
поделиться
  1. Catching and rethrowing an exception that you cannot handle is nothing more than a waste of processor time. If you can't do anything with or about the exception, ignore it and let the caller respond to it.
  2. If you want to log every exception, a global exception handler will do just fine. In .NET, the stack trace is an object; its properties can be inspected like any other. You can write the properties of the stack trace (even in string form) to your log of choice.
  3. If you want to ensure that every exception is caught, a global exception handler should do the trick. In point of fact, no application should be without one.
  4. Your catch blocks should only catch exceptions that you know that you can gracefully recover from. That is, if you can do something about it, catch it. Otherwise, let the caller worry about it. If no callers can do anything about it, let the global exception handler catch it, and log it.
1
ответ дан 2 December 2019 в 04:09
поделиться

Хорошо, прочитав все ответы, в которых говорится, что у вас должна быть одна попытка / уловка на верхнем уровне, я собираюсь взвесить альтернативное представление.

Я бы не стал добавьте try / catch в каждый метод , это далеко не так. Но я использовал бы try / catch для участков кода, которые, как я ожидал, потерпят неудачу (например, открытие файла), и где я хотел бы добавить дополнительную информацию к исключению (чтобы быть зарегистрированным выше по цепочке) .

Сообщение трассировки стека и сообщение «В разрешении отказано» может быть достаточно, чтобы позволить вам, как программисту, понять, что пошло не так, но моя цель - предоставить пользователю значимую информацию, например «Не удалось открыть файл 'C: \ lockedfile.txt'. В доступе отказано.».

Как в:

private void DoSomethingWithFile(string filename)
{
    // Note: try/catch doesn't need to surround the whole method...

    if (File.Exists(filename))
    {
        try
        {
            // do something involving the file
        }
        catch (Exception ex)
        {
            throw new ApplicationException(string.Format("Cannot do something with file '{0}'.", filename), ex);
        }
    }
}

I '

4
ответ дан 2 December 2019 в 04:09
поделиться

Я бы рассмотрел возможность использования ELMAH для обработки исключений, что в значительной степени является концепцией «позволить исключениям произойти». ELMAH позаботится о том, чтобы их регистрировать, и вы даже можете настроить его на отправку вам электронной почты, когда исключения для определенного проекта достигают или превышают определенный порог. В моем отделе мы стараемся держаться подальше от блоков try / catch. Если что-то не так в приложении, мы хотим сразу узнать, в чем проблема, чтобы мы могли ее исправить, вместо того, чтобы подавлять исключение и обрабатывать его в коде.

Если происходит исключение, это означает, что что-то не так право. Идея состоит в том, чтобы заставить ваше приложение делать только то, что должно делать. Если он делает что-то другое и вызывает исключения, ваш ответ должен заключаться в том, чтобы исправить причину, по которой это ' происходит, не позволяйте этому случиться и обрабатывайте это в коде. Это просто моя / наша философия, и она не для всех. Но нас всех слишком много раз сжигало приложение, "съедающее" исключение по той или иной причине, и никто не знает, что что-то не так.

И никогда, никогда, НИКОГДА не поймает общее исключение. Всегда, всегда, всегда перехватывает наиболее конкретное исключение, чтобы, если возникло исключение, но это не тот тип, который вы ожидаете, вы снова узнаете, потому что приложение выйдет из строя. Если вы просто поймаете (Исключение e), то независимо от того, какое исключение выбрано, ваш блок catch теперь будет отвечать за каждый отдельный тип исключения, которое может быть создано. А если этого не произойдет, вы столкнетесь со всеми исключениями, которые "съедают",

1
ответ дан 2 December 2019 в 04:09
поделиться

Исключения реализованы таким образом, что они не требуют затрат, если только не возникнут.

Это означает, что для меня разветвления производительности не являются сильным аргументом против. Исключительные условия обычно бывают ... исключительными.

0
ответ дан 2 December 2019 в 04:09
поделиться

На самом деле избегайте детальных попыток / перехватов. Позвольте исключению пройти вверх по стеку и попасть на как можно более высокий уровень. Если у вас есть конкретная проблема, то поместите ведение журнала в режим немедленного перехвата, если вас беспокоит каскадирование исключений - хотя вы все равно сможете разрешить их, углубившись во внутренние исключения.

Обработка исключений не должна выполняться запоздалая мысль. Убедитесь, что вы делаете это постоянно. Я видел, как многие люди от начала до конца каждого метода вводили широкую команду try / catch и улавливали общее исключение. Люди думают, что это помогает им получить больше информации, хотя на самом деле это не так. В некоторых случаях больше значит меньше, потому что меньше значит больше. Я никогда не устаю от аксиомы "

0
ответ дан 2 December 2019 в 04:09
поделиться

Вы можете видеть все в трассировке стека - не нужно пробовать / ловить каждый метод.

Придерживайтесь нескольких правил:

  1. Используйте try / catch, только если вы хотите использовать настраиваемый тип исключения.
  2. Определите новый тип исключения, только если верхние уровни должны знать, что
  3. Try / catch на верхнем уровне вместо того, чтобы делать это для каждого метода
9
ответ дан 2 December 2019 в 04:09
поделиться

Я определенно не использую оболочку try catch для каждого метода (как ни странно, я делал это, когда только начал, но это было до того, как я научился лучшим способам).

1) Чтобы предотвратить программа от сбоя и пользователи теряют свою информацию, я делаю этот

                runProgram:
                try
                {
                    container.ShowDialog();
                }
                catch (Exception ex)
                {
                    ExceptionManager.Publish(ex);
                    if (MessageBox.Show("A fatal error has occurred.  Please save work and restart program.  Would you like to try to continue?", "Fatal Error", MessageBoxButtons.YesNo) == DialogResult.Yes)
                        goto runProgram;
                    container.Close();
                }

контейнер - это то место, где мое приложение запускается, так что это в основном помещает оболочку вокруг всего моего приложения, так что ничто не вызывает сбоя, который не может быть восстановлен. Это один из тех редких случаев, когда я действительно не против использования goto (это небольшой объем кода, который все еще хорошо читается)

2) Я ловлю исключения только в методах, где я ожидаю, что что-то может пойти не так (например, как тайм-аут).

3) Для удобства чтения, если у вас есть блок try catch с кучей кода в разделе try и кучей кода в разделе catch, лучше извлечь этот код в хорошо названный метод.

   public void delete(Page page) 
   {
      try 
      {
         deletePageAndAllReferences(page)
      }
      catch (Exception e) 
      {
         logError(e);
      }
   }
1
ответ дан 2 December 2019 в 04:09
поделиться

Чтобы сделать это в момент возникновения, вам все равно понадобится try / catch. Но не обязательно везде ловить исключения. Они распространяются вверх по стеку вызовов, а когда их поймают, вы получите трассировку стека. Так что, если возникнет проблема, вы всегда можете добавить больше попыток / уловок по мере необходимости.

Рассмотрите возможность проверки одной из многих доступных фреймворков журналирования.

1
ответ дан 2 December 2019 в 04:09
поделиться

Как избежать try / catch в каждом методе, но все же записывать ошибку в том месте, где она произошла?

Это зависит от хоста env. Asp.Net, WinForms и WPF имеют разные способы захвата необработанных исключений. Но как только глобальный обработчик передает экземпляр исключения, вы можете определить точку выброса исключения, поскольку каждое исключение включает трассировку стека.

0
ответ дан 2 December 2019 в 04:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: