Возврат вопроса об исключении - PullRequest
0 голосов
/ 28 ноября 2009

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

-Почему вы не хотите, чтобы немедленный блок catch обрабатывал исключение, а скорее что-то над ним?

-Кроме того, я часто читал, что вы должны обрабатывать только те исключения, которые вы можете "обработать". Означает ли это, что вы на самом деле что-то делаете, например, пытаетесь повторить операцию?

Ответы [ 4 ]

3 голосов
/ 28 ноября 2009

Возможно, вы захотите перехватить исключение (например, файл не найден) и выполнить некоторую обработку - например, если вы открываете два файла, а второй файл отсутствует, вам необходимо снова закрыть первый файл, прежде чем продолжить, чтобы он не был оставлен открытым.

После этого вы можете сообщить вызывающему абоненту, что произошла ошибка, поэтому вы повторно генерируете то же исключение или новое исключение, описывающее проблему.

В некоторых случаях, если вы получаете исключение, ваш код не может знать, является ли это ошибкой или нет (например, если вас просят загрузить файл XML, но вы получаете исключение File Not Found, это то, что ошибка, или вы должны вернуть пустой результат XMl?). В этих случаях вы либо хотите повторно выдать исключение, либо не обрабатывать все это, и позволить вызывающему коду решить, как решить проблему.

1 голос
/ 28 ноября 2009

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

0 голосов
/ 29 октября 2012

Исключение "обрабатывается", если метод, который его перехватил, может удовлетворить свою конструкцию. Например, контракт для подпрограммы OpenRecentDocument, которая вызывается, когда пользователь выбирает элемент в меню «последние файлы», может указывать, что он должен (1) успешно открыть окно документа или (2) безуспешно попытаться открыть окно документа, откатить любые побочные эффекты, возникающие в результате попытки, и уведомить пользователя о том, что произошло. Если OpenRecentDocument ловит исключение при попытке открыть файл, но может откатить любые побочные эффекты от попытки и уведомить пользователя, подпрограмма выполнит свой контракт и, следовательно, должна вернуться без повторного выброса исключения.

Одна неприятная «ошибка» во всем этом заключается в том, что не существует каких-либо стандартных средств, с помощью которых подпрограммы, которые выдают исключение, могут указывать, привела ли их попытка к выполнению побочных эффектов, которые нельзя было откатить. Не существует неотъемлемого способа, например, отличить InvalidOperationException, который неожиданно возникает при обновлении общей структуры данных (что может означать, что другие открытые документы могли быть повреждены), от InvalidOperationException, который возникает при обновлении связанных данных с загружаемым документом, даже если кто-то предвидел последнюю возможность и предоставил ее. Лучшее, что можно сделать, это либо попытаться поймать любой InvalidOperationException, который может произойти в последней ситуации рядом с местом, где это происходит, инкапсулировать это исключение в некоторый другой тип исключения и выбросить его, либо структуры данных поддерживают объект " «поврежден» и убедитесь, что, если структура данных будет повреждена, все будущие операции с ней будут проходить как можно более чисто. Ни один из подходов не является элегантным. Более распространенный подход, который, вероятно, можно охарактеризовать как «надежда на лучшее», обычно работает.

0 голосов
/ 28 ноября 2009

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

Например, немедленный блок работает с файлом. Вызывающий может попытаться открыть файл из разных мест (в процессе «проверки») и игнорировать несколько ошибок, если хотя бы одна из них удалась. Другая часть кода может рассматривать самую первую неудачную попытку как ошибку. Блок вызывающего абонента может выбрать для уведомления пользователя о возникновении ошибки, возможно, сообщить ему / ей некоторую полезную информацию о том, как решить проблему. Также приятно предоставить средства для уведомления о поддержке проблемы - своего рода диалог, позволяющий пользователю обратиться за помощью, описать проблему и отправить сообщение. В этом сообщении вы можете прикрепить журналы, некоторую информацию о среде, такой как ОС, версии фреймворков, программ, возможности браузера, все, что вам нужно для диагностики проблемы (если пользователь разрешает вам делать это).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...