Запутался в обработке ошибок в VB6 и использовании On Error GoTo - PullRequest
3 голосов
/ 27 января 2012

Мне нужно устранить неполадки со старым кодом VB6, и я запутался в использовании «On Error».В приведенном ниже примере, если я окружу конкретную строку кода, которую я хочу проверить с помощью On Error GoTo и ErrHandler1, это ЕДИНСТВЕННАЯ строка, которая проверяется.Или будет включено деление на ноль, если оно находится в том же Sub?

On Error GoTo ErrHandler1
If Not Exists(BaseDirectory + "\ARCHIVE") Then _
   MkDir BaseDirectory + "\ARCHIVE"

ErrHandler1:
   Call MsgBox(Err.Number & vbCrLf & Err.Description, vbExclamation, App.Title)


intValue1 = 12
intValue2 = 0
intValue3 = intValue1 / intValue

Спасибо.

Ответы [ 3 ]

8 голосов
/ 27 января 2012

Деление на ноль будет включено и обработано, и это, вероятно, создаст цикл в вашем образце ...

Правильный подход такой

On Error GoTo ErrHandler1
If Not Exists(BaseDirectory + "\ARCHIVE") Then _
   MkDir BaseDirectory + "\ARCHIVE"

On Error Goto 0 'this will un-hook you error handler

intValue1 = 12
intValue2 = 0
intValue3 = intValue1 / intValue  'this will be an un-managed error

Exit Sub 'this make sure that msgbox is shown only when the error happens

ErrHandler1:
   Call MsgBox(Err.Number & vbCrLf & Err.Description, vbExclamation, App.Title)
5 голосов
/ 27 января 2012

Деление на ноль выполняется только в том случае, если MkDir не вызывает ошибку.

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

Таким образом, код не имеет смысла в том виде, в каком он есть, обработчик ошибок должен быть перемещен дальше вниз по коду (ниже подпрограммы exit), чтобы он вызывался только один раз:

On Error Goto ErrHandler1

    'some code

    exit sub
ErrHandler1:
    msgbox "There was an error"

Если вы хотите обрабатывать обе операции отдельно, вы можете сделать это:

On Error GoTo ErrHandler1
If Not Exists(BaseDirectory + "\ARCHIVE") Then _
   MkDir BaseDirectory + "\ARCHIVE"

DoCalc:
    On Error GoTo Errhandler2
    intvalue1 = 12
    intvalue2 = 0
    intvalue3 = intvalue1 / intvalue

    Exit Sub

ErrHandler1:
   Call MsgBox("Error making directory - " & Err.Number & vbCrLf & Err.Description, vbExclamation, App.Title)
   Resume DoCalc:

Errhandler2:
    Call MsgBox("Error doing arithmetic - " & Err.Number & vbCrLf & Err.Description, vbExclamation, App.Title)
1 голос
/ 27 января 2012

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

On Error GoTo procErrorHandler

    If Not Exists(BaseDirectory + "\ARCHIVE") Then
        MkDir BaseDirectory + "\ARCHIVE"
    End If

    intvalue1 = 12
    intvalue2 = 0
    intvalue3 = intvalue1 / intvalue

ProcExit:
    Exit Sub

procErrorHandler:
    Call MsgBox("There was an error in the procedure. Error " & CStr(Err.Number) & ", " & Err.Description, vbExclamation, App.Title)
    Resume ProcExit  ' A chance to do any cleanup needed

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

On Error Resume Next

    If Not Exists(BaseDirectory + "\ARCHIVE") Then
        MkDir BaseDirectory + "\ARCHIVE"
    End If
    ' check for errors making the directory
    If Err.Number <> 0 Then
        Call MsgBox("Error making directory - " & Err.Number & vbCrLf & Err.Description, vbExclamation, App.Title)
    End If

    intvalue1 = 12
    intvalue2 = 0
    intvalue3 = intvalue1 / intvalue
    ' check for errors getting intvalue3
    If Err.Number <> 0 Then
        Call MsgBox("Error doing arithmetic - " & Err.Number & vbCrLf & Err.Description, vbExclamation, App.Title)
    End If

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