Как вы обрабатываете ошибки в обработчиках ошибок в VB6? - PullRequest
4 голосов
/ 11 февраля 2009

Я часто сталкиваюсь с такой ситуацией в моих приложениях VB6

Private Sub DoSomething

  On Error Goto err1

  Call ProcessLargeBatch1
  Call ProcessLargeBatch2
  '... more ...'

  Exit Sub

err1:
  Call Cleanup 'Specific for DoSomething'
  Call HandleError 'General error handling: Logging, message box, ...'

End Sub

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

Что мне делать в этом случае? Я бы добавил On Error Resume Next в обработчик ошибок, но он удаляет существующий объект Err. Добавление обработчика ошибок к Cleanup имеет ту же проблему.

Каков наилучший способ гарантировать, что исходные ошибки все еще обрабатываются / регистрируются?

РЕДАКТИРОВАТЬ : Еще одна проблема заключается в том, что я также хочу уведомить пользователя об ошибке. Иногда важно, чтобы очистка происходила быстро, и я не хочу, чтобы окно сообщения блокировало приложение на долгое время и выполняло очистку после того, как пользователь подтвердил ошибку.

Ответы [ 5 ]

4 голосов
/ 11 февраля 2009

Сначала прочитайте всю информацию из объекта Err, который вам понадобится, то есть номер, описание и т. Д., Затем устраните ошибку и сделайте, что вы хотите.

Измените способ информирования пользователя об использовании кэшированных вами значений, а не об использовании самого объекта Err.

3 голосов
/ 11 февраля 2009

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

При возникновении ошибки вам нужно:

  1. Очистить
  2. Журнал ошибок
  3. Снова вызвать ошибку через Err.Raise

Это будет работать вверх по стеку вызовов до события, которое вызвало исходный код. Тогда последовательность станет

  1. Очистить
  2. Журнал ошибок
  3. Отображение диалогового окна уведомления об ошибках

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

Вы хотите убедиться, что КАЖДОЕ событие имеет обработчик ошибок. Не каждая процедура требует одного, но определенно каждое событие. Необработанные ошибки в событии приведут к неожиданному завершению работы приложения VB6.

2 голосов
/ 11 февраля 2009

Если я могу обработать все ошибки в одном месте, я обычно добавляю в структуру что-то вроде этого:

Public Sub SubThatShouldHandleErrors()
Const ROUTINE_NAME = "SubThatShouldHandleErrors"
On Error Goto Catch

    ' "normal" processing here...

Finally:
    ' non-error case falls through to here
    ' perform clean-up that must happen even when an error occurred
    On Error Goto 0 ' reset: not really needed any more, but it makes me feel more comfortable
    Exit Sub

Catch:
    ' Error handling here, I may have logging that uses ROUTINE_NAME
    Resume Finally

End Sub

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

1 голос
/ 11 февраля 2009

Сначала зарегистрируйте вашу ошибку. Затем сделайте On Error Resume Next. Инкапсулируйте очистку в методах, которые имеют свою собственную обработку ошибок. Это должна быть ваша лучшая ставка.

0 голосов
/ 11 февраля 2009

Мне действительно не нравятся обработчики ошибок. Это то, что я делаю;

  • Создайте класс или модуль Error, который содержит все свойства, которые содержит встроенный, а также метод CopyError, который заполняет эти свойства из объекта err.
  • Следите за ошибками, где они могут появиться:

.

' lots of code that will probably work
On Error Resume Next
Open "c:\filethatdoesntexist.txt" For Input As #1
Error.CopyError
On Error Goto 0
Select Case Error.Number
    Case 53'File doesn't exist
        ' handle that error here
    Case 0
        ' no error
    Case Else
        ' Just throw the error on
        Err.Raise Error.Number, Error.Description, ...
End Select
' more code that will probably work
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...