2009-03-05 5 views
9

Мне недавно пришлось разработать дополнительный модуль для существующего сервиса, разработанного коллегой. Он поставил попробовать/поймать блок в основной рабочей функции для ловли всех unhadled исключения, которые пузырились до этого уровня, протоколирование их вместе с стека трассировки информации и т.д.:Как реализовать обработку исключений верхнего уровня?

try 
{ 
    // do main work 
} 
catch(Exception ex) 
{ 
    // log exception info 
} 

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

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

Каков ваш совет по этой проблеме?

Кстати, проект написан на C#, но меня также интересуют ответы для языков не .NET.

+0

См. Также http://stackoverflow.com/questions/576532/is-dying-is-awesome-preferred – Brian

ответ

10

Верните его обратно.

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

Регистрация в порядке.

Вы можете дополнительно использовать символ DEBUG, определенный Visual Studio, для отладочной сборки в качестве флага.

... 
    } catch(Exception e) { 
#if DEBUG 
      throw; 
#else 
      log as usual 
#endif 
    } 

Так что в следующий раз, когда требуется модификация, флаг отладки должен быть установлен в true и будет появляться исключение.

+0

Хм, мне нравится флаг отладки! – Treb

+0

Разве он не должен использовать 'throw' not 'throw e'? В противном случае трассировка стека очищается (или что-то - не слишком уверенное). – strager

+0

@strager: Да! В приведенном выше примере будет замаскировано исходное исключение. Просто используйте «throw». –

2

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

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

4

В любом приложении Java, вы просто о всегда нужно определять обработчик исключений для неперехваченными исключений с чем-то вроде этого:

Thread.setDefaultUncaughtExceptionHandler(...); 

где объект, который будет ловить эти пойманные исключения, по крайней мере войти провал так у вас есть шанс узнать об этом. В противном случае нет никакой гарантии, что вы даже будете уведомлены о том, что Thread принял исключение - если только это не ваш основной поток.

В дополнение к этому, в большинстве моих потоков есть попытка/поймать, где я поймаю RunnableException (но не Error) и запустил его ... некоторые потоки умрут, когда это произойдет, другие будут регистрироваться и игнорировать, другие покажут жалобу пользователю и позволят пользователю решить, в зависимости от потребностей приложения.Этот try/catch находится в самом корне Thread, в методе Runnable.run() или его эквиваленте. Поскольку try/catch находится в корневой части Thread, нет необходимости иногда отключать этот catch.

Когда я пишу на C#, я кодирую аналогично. Но все это зависит от потребности приложения. Является ли Исключение исключением, которое приведет к повреждению данных? Тогда не поймите и не проигнорируйте это. ВСЕГДА запишите его, но затем пусть приложение умирает. Однако большинство исключений не имеют такого рода.

2

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

+0

Я понимаю, откуда вы родом, но существует отличный класс исключений, в которых ваша программа может работать в деградированном состоянии, но все равно выполняться, где вы действительно хотите исключить ловушки и журналы. Стабильность имеет значение. Вам просто нужно знать, где вы НЕ МОЖЕТЕ сделать это. – Eddie

+0

@ Eddie - Правда, эта область всегда очень зависима от приложения и пользователя. Мы все хотели бы сделать надежные приложения для исполнителей, которые никогда не сбой, но тогда на самом деле называет :). Ничто не сравнится с обширным предварительным тестированием, охватом кода и бета-версиями с реальными клиентами, чтобы получить уверенность. –

1

Если вы хотите увидеть исключение, когда это происходит, в Visual Studio вы можете перейти в меню DEBUG, выбрать EXCEPTIONS, и вы можете сообщить отладчику, что Break, как только генерируется Исключение. Вы даже можете выбрать тип исключений. :)

+0

И как это работает, когда эта программа работает как служба? – Treb

+2

Если вы загружаете сервис в память, а затем присоединяете к нему, все это работает так, как вы привыкли. Если он удален (как в сервисе на сервере где-то), вам необходимо установить на сервер, чтобы разрешить удаленную отладку. Если вам нужно сделать это в STARTUP, вы можете добавить «фиктивный сервис» в свой исполняемый файл, запустите ТО, что один (который загружает EXE в память), присоединяется к процессу, а затем запускает другую службу (с полными возможностями отладки). Он работает БОЛЬШОЙ. –

Смежные вопросы