Это нормально, чтобы всплыть исключение на вершину стека? - PullRequest
10 голосов
/ 03 мая 2011

Можно ли позволять исключению пузыриться на вершине стека, вместо того, чтобы перехватывать его в каждом методе? .. Должны ли мы делать это в любом случае?.. Есть ли какие-либо тонкие проблемы или побочные эффекты при таком подходе (например, потеря деталей об исключении, трассировке стека или внутренних деталях исключения и т. Д.)?


Хотя мой вопросВ общем, сценарий в моем случае в настоящее время выглядит следующим образом:

Я перемещаю существующую веб-службу WSE3 в WCF, и поэтому y клиенты являются клиентами WSE3.

Я добавил поведение, чтобы FaultException сообщалось на стороне клиента всякий раз, когда это происходит в службе WCF.Когда в методе OperationContract возникает исключение, я получаю сообщение об исключении на стороне клиента без каких-либо проблем.Но всякий раз, когда это происходит в методах, отличных от OperationContract s, я как-то сталкиваюсь с проблемой безопасности.Я не могу определить точную причину.

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

Ответы [ 3 ]

15 голосов
/ 03 мая 2011

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

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

  • Обработать его (т.е. не перебрасывать)
  • Добавить нескольковажная контекстная информация

Я поддерживал приложения, в которых каждый nethod был окружен блоком try-catch, и я буквально имею в виду каждый метод:

public void DoSomething()
{
    try
    {
        throw new NotImplementedException();
    }
    catch (Exception ex)
    {
        throw ExceptionHandler.CreateException(ex, "DoSomething");
    }
}

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

В случае, когда ваше исключение должно проходить некоторую границу межпроцессного режима (например, в службе WCF)) затем в тот момент, когда ваше исключение становится доступным миру, который вы, возможно, захотите сначала перехватить, зарегистрировать, а затем повторно выбросить исключение в совместимом формате для границы IPC, чтобы у вас был журнал всех сбоев в вашем сервисе

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

7 голосов
/ 03 мая 2011

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

Обновление

В ответ на ваш вопрос, нет, все детали (включая трассировку стека, где возникло исключение) передаются с объектом исключения.

То, что вы увидите , иногда выглядит как

highLevelFunction(){
   try {
     lowerLevelFunction();
   } catch (LowLevelException e){
     throw HighLevelException(e);
   }
}

или цепочка исключений . Что происходит там, у вас есть какое-то низкоуровневое исключение типа «делить на ноль»; вы ловите его и создаете новое исключение, такое как «исключение данных», чтобы сделать его более значимым для подпрограмм, вызывающих highLevelFunction.

(PS простите, если это не идеальный синтаксис C #, я не так много писал в последнее время.)

2 голосов
/ 03 мая 2011

Если у вас есть полные приложения (GUI, бизнес, данные), дайте им всплыть до пользовательского интерфейса и обработайте его здесь, на событиях.Это дает вам возможность отображать сообщение пользователю одновременно.Он также перехватывает его до точки начала действия (т. Е. Когда пользователь сделал действие X, это произошло).Поймать его в каждом методе слишком сложно и не нужно, так как вы можете просто записать трассировку стека, чтобы найти источник в любом случае.Если вы создаете приложение промежуточного программного обеспечения, попробуйте обработать его на интерфейсе или всплыть - в зависимости от того, как будет использоваться промежуточное программное обеспечение.

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