2010-04-08 3 views
68

Я начал использовать блоки try catch (немного поздно, я знаю!), Но теперь я не уверен, что делать с исключением, как только я его поймал. Что мне делать?Я поймал исключение !! Что теперь?

Try 
    connection.Open() 
    Dim sqlCmd As New SqlCommand("do some SQL", connection) 
    Dim sqlDa As New SqlDataAdapter(sqlCmd) 
    sqlDa.Fill(dt) 
Catch ex As SQLException 
    ' Ahhhh, what to do now!!!? 
Finally 
    connection.Close() 
End Try 
+0

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

+71

получить стеклянную банку и тыкать некоторые отверстия в крышке ;-) –

+27

Исключения: Gotta catch em all! – CiscoIPPhone

ответ

23

Что вы хотите от этого сделать? Это полностью зависит от вашего приложения.

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

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

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

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

+0

Я бы также рекомендовал уменьшить количество кода внутри вашего блока, особенно в приведенном выше примере. Вы a) подключаетесь к базе данных и b) выполняете команду SQL, оба из которых могут вызывать множество исключений. Поместите каждый в отдельный try catch (или проанализируйте свое ex/exception), чтобы у вас было лучшее представление о том, с какой ошибкой вы сталкиваетесь (были ли вы пробиты в глаза или были нанесены на ногу?) – CResults

+0

Вы могли бы также конец приложения, поскольку исключение является фатальным –

+1

@ Victor Hurdugaci, что исключение не является фатальным, если только программа не требует, чтобы данные работали. Я всегда стараюсь не заканчивать программу, потому что обычно вы можете позволить пользователю повторить попытку, повторите попытку, сообщите, что что-то не так, сообщите пользователю, что делать. Мне не нравятся программы, которые я использовал, чтобы просто завершить работу. – msarchet

0

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

0

Это зависит исключительно от контекста. Возможные варианты: «Использовать данные по умолчанию вместо данных из базы данных» и «Отобразить сообщение об ошибке пользователю».

0

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

9

Это зависит от того, что sql делает на самом деле. Это что-то:

  • что пользователь сделал? Возможно, создать учетную запись или сообщение - тогда вам нужно сообщить пользователю, что что-то не так
  • что приложение действительно? Как очистка журналов или что-то подобное? Это фатально? Может ли приложение продолжить? Это что-то, что можно игнорировать - возможно, повторилось? Должен ли администратор быть объявлен?

Начните с этими вопросами, то они, как правило, приводят к ответам о том, как лечить исключения

5

Если вы не ожидали ошибки (API говорит, что это может occurr) и может обрабатывать его (есть очевидный шаг если произойдет исключение), вы, вероятно, захотите сбой при большом количестве шума. Это должно произойти во время тестирования/отладки, чтобы ошибка могла быть исправлена ​​до того, как пользователь ее увидит!

Конечно, как отмечают комментаторы, пользователь никогда не должен действительно видеть весь этот шум. Высокоуровневый try/catch или какой-либо другой метод (EMLAH, я слышу для веб-проектов .net) можно использовать, чтобы показать пользователю приятное сообщение об ошибке («Ой, что-то пошло не так!Что вы пытаетесь сделать? ») С кнопкой отправки ...

В основном, я хочу сказать следующее: Не поймайте ошибки, о которых вы не знаете, как обращаться! (за исключением высоких -level handler). Сбой рано и с максимальной информацией. Это означает, что вы должны зарегистрировать стек вызовов и другую важную информацию, если это вообще возможно для отладки.

+3

С другой стороны, никогда не «крушить с большим количеством шума» перед глазами пользователя. Скажите что-то вроде «Ops, что-то пошло не так, мы над этим работаем». Нет подробностей, чтобы увидеть их публично. – 2010-04-08 12:32:36

+4

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

2

Если вы не знаете, как реагировать на него , не улавливайте исключения.

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

1

Во-первых, если у вас нет возможности обработать исключение, вы не должны его ловить (logging can be done via exception event handlers without catching).

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

20

Это зависит от вашей бизнес-логики, но вы можете сделать одно или несколько из следующих действий.

  • Откат транзакции
  • Войдите ошибку
  • оповещения любого пользователя приложения
  • Повторите операцию
  • Rethrow исключение

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

Хорошая статья об обработке исключений VB.NET - Exception Handling in VB.NET от Rajesh VS.

+0

Я предлагаю по крайней мере три лучших для большинства ошибок SQL. – HLGEM

64

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

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

+2

Я не согласен с этим и отредактировал свой ответ, чтобы понять, почему. – NibblyPig

+1

+1 - и .. Если вы ничего не можете здесь поделать, не поймайте его здесь. –

+0

@SLC - я думаю, вы неправильно интерпретируете ответ. Конечно, ваше приложение не должно blithely crash из-за необработанного исключения, и обработчик уровня приложения обычно является хорошей идеей. Захват исключения только потому, что вы можете ожидать, что он не всегда лучший дизайн. –

2

Следует иметь в виду, что в тех разделах, где вы чувствуете, что хотите использовать try/catch, вы должны перемещать ваши инструкции Dim из блока try. Вы можете назначить им значения внутри блока, но если вы определите их внутри блока try, у вас не будет доступа к этим переменным внутри секции catch, поскольку они будут недоступны в этой точке.

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

1

FYI, вам не нужно использовать улов, чтобы иметь окончательное утверждение.

Иногда люди генерируют новое исключение, которое более firendly и добавляет исходное исключение в качестве внутреннего исключения.

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

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

2

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

catch (Exception ex) 
{ 
    /* I don't know what to do.. *gulp!* */ 
} 

Ясно, что это нехорошо, потому что происходят плохие вещи, и никаких действий не предпринимается. Исключайте только исключения, которые действуют!

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

Взяв все это вместе, вы можете найти эту стратегию полезной: 1. поймать определенные исключения, которые, как вы знаете, могут произойти (DivideByZeroException, SQLException и т. Д.) И уклониться от общего исключения Exception; 2. Повторно поднимите исключение после его обработки. например

catch (SQLException ex) 
{ 
    /* TODO: Log the error somewhere other than the database... */ 
    throw; // Rethrow while preserving the stack trace. 
} 

Что вы действительно можете сделать с помощью SQLException? Удалось ли соединение с базой данных? Это был плохой запрос? Вероятно, вы не хотите добавлять для этого всю логику обработки, и, кроме того, что, если это то, чего вы не ожидали? Поэтому просто обработайте исключение, если можете, re-raise его, если вы не уверены, что он разрешен и изящно обрабатывает его на уровне (например, покажите сообщение типа «Что-то пошло не так, но вы, возможно, Продолжить работу Подробная информация: «[ex.Message]». Прерывание или повтор? »)

HTH!

John Saunders, спасибо за исправление.

+2

Тщательная регистрация и повторное метание. Если вы регистрируетесь на каждом уровне, вы можете получить в своем журнале ошибок много и много записей одного и того же исключения. Google «log rethrow» для нескольких советов по правильному пути. – WCWedin

+0

@JohnSaunders Вам следует рассмотреть возможность удаления комментария, когда ответ был исправлен. –

+0

@Mark: спасибо. Я не знал об изменениях. Удалено нисходящее. –

14

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

Using connection As New SqlConnection("connection string here"), _ 
     sqlCmd As New SqlCommand("do some SQL", connection), _ 
     sqlDa As New SqlDataAdapter(sqlCmd) 

    sqlDa.Fill(dt) 
End Using 

Не только там нет Try/Стопор/Наконец, нет никакого открытия или закрытия. Функция .Fill() задокументирована как открытие соединения, если требуется, и блок «Использование» будет абсолютно уверен, что он закрыт правильно, , даже если выбрано исключение.

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

На самом деле, эта способность исключений «пузырится» в вашем коде, что делает их такими ценными. Если вы всегда поймаете исключение прямо там, где оно выбрано, то исключения не добавляют большого значения за рамки старого синтаксиса «On Error Goto X».

0

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

Exception Handling Application Block как часть Enterprise Library 5.0 является рекомендуемой структурой для использования.

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

0

Ну, Это зависит прежде всего, если вы делаете деньги из своего приложения или нет. По моему опыту никто (кто платил за приложение) не любит, чтобы он рушился и закрывался, вместо этого они предпочитают короткое и пояснительное сообщение об ошибке и второй шанс продолжить то, что они делают, плюс возможность сохранить/экспортировать их измененные данные. ИМО - лучшая практика заключается в том, чтобы поймать все, что может вызвать что-то неправильное из-под вашего контроля, например операции ввода-вывода, связанные с сетью задачи, e.t.c. и отобразить соответствующее сообщение пользователю. В случае, если исключение выбрано из-за ошибки, связанной с логикой, лучше не ловить ее, так как это поможет вам найти и исправить фактическую ошибку.

Надеюсь, это поможет.

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