Глобальная попытка поймать - PullRequest
8 голосов
/ 30 марта 2012

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

Я пишу приложение Silverlight, в котором каждое исключение должно создавать MessageBox, который говорит что-то вроде «Извините за неудобства».

Поскольку я не могу гарантировать, что мой код будет свободен от исключений, мой коллега поручил мне попробовать перехватить каждый метод (пару сотен) следующим образом:

public void Method1()
{
    try
    {
        ...
    }
    catch (Exception e)
    {
        MessageBox.Show("Something went wrong, we apologize for the inconvenience. \n" + e.Message);
    }
}

public void Method2()
{
    try
    {
        ...
    }
    catch (Exception e)
    {
        MessageBox.Show("Something went wrong, we apologize for the inconvenience. \n" + e.Message);
    }
}

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

Есть ли какие-нибудь альтернативы, такие как глобальная попытка поймать, которую я могу использовать?

Thanx! / Mike

Ответы [ 3 ]

9 голосов
/ 30 марта 2012

вы всегда можете обработать событие AppDomain.UnhandledException

5 голосов
/ 30 марта 2012

Пробовать-ловить в каждом отдельном методе глупо. Но:

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

У меня был похожий случай с продуктом, который уже используется нашими клиентами. Это был проект WPF, похожий на silverlight. Моя работа заключалась в том, чтобы избавиться от ошибок в старом плохом коде, который никто до сих пор не освоил. Приложение взаимодействовало с другими программами в Windows, и было невозможно предвидеть, что может пойти не так в других средах.

У меня были эти проблемы :

  1. Программа перестала работать из-за необработанных исключений.
  2. Трудно было понять, что пошло не так, чтобы исправить ошибки. Наши клиенты обычно сообщают об ошибках, посылая по электронной почте дампы экрана, где было трудно увидеть, что произошло.

Мой заход был:

  1. Отлов исключений для выбран «конечные точки пользователя и системы». Это, как правило, обработчики событий для нажатия кнопки, перетаскивания, команд навигации и т. Д. Со стороны пользователя, и, как правило, окна сообщений и ответов сервера со стороны системы.
  2. Класс OopsBox, чтобы сделать неожиданную ошибку обработкой одной строки в каждом улове. Каждый улов имеет максимально дружеское сообщение и скрывает грязные вещи за кнопкой расширения. Поле также используется для сообщений об ошибках ожидаемых , и в этих случаях нет кнопки расширения и грязной информации для отображения, поскольку мы знаем, что уже пошло не так. OopsBox

Мы получили это:

  • Пользователям было легче найти обходной путь, поскольку они не были выброшены из контекста в случаях, когда ошибка не была серьезной.
  • Было легче понять, что пошло не так, когда сообщалось о каком-то неожиданном поведении.
  • Коробки Oops начинались на больших частотах, но я считаю, что продукт стабилизируется быстрее, и блоки Oops намного реже.
  • До сих пор, когда что-то идет не так у клиента, я получаю стек вызовов от него по электронной почте. :)

Это Стоимость Это:

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

Резюме

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

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

  • Ящик с ошибкой или нет, попробуйте найти способ не выбрасывать пользователя из контекста, когда что-то идет не так. Трудно заставить его работать во всех случаях, но это фатально, когда это происходит.

4 голосов
/ 30 марта 2012

Вы можете захватывать незапланированные (и потоковые) исключения, используя свойства Application.ThreadException и AppDomain.CurrentDomain.UnhandledException.

Ваш Main будет выглядеть примерно так:

[STAThread]
static void Main() { 

    if (Debugger.IsAttached) {
        Run();
        return;
    } 

    Application.ThreadException += ApplicationThreadException;
    AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;
    Run();
}

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

Функция Run довольно проста

    static void Run() {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm());
    }

А затем два обработчика исключений.

    static void ApplicationThreadException(object sender, ThreadExceptionEventArgs e) {
        ErrorInformationDialog eid = new ErrorInformationDialog(e.Exception.Message, e.Exception);
        eid.ShowDialog();
    }

    static void CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) {
        ErrorInformationDialog eid = new ErrorInformationDialog(e.ExceptionObject as Exception);
        eid.ShowDialog();
    }

А ErrorInformationDialog - это просто форма, которую я собрал, чтобы отобразить уведомление об ошибке и дать инструкции по ее уведомлению.

...