Запутался в обработке ошибок в VB6 и использовании On Error GoTo
Мне нужно устранить неполадки в каком-то старом коде VB6, и я запутался в использовании "On Error". В приведенном ниже примере, если я окружаю конкретную строку кода, которую я хочу протестировать с помощью On Error GoTo и ErrHandler1, это единственная строка, которая тестируется. Или будет ли деление на ноль включено, если оно находится в той же самой подложке?
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 ответов:
Деление на ноль будет включено и обработано, и это, вероятно, создаст цикл в вашем образце...
Правильный подход таков
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)
Деление на ноль обрабатывается только в том случае, если MkDir не вызывает ошибки.
Это означает, что он будет замкнут на метку
ErrHandler1, и еще одна ошибка будет сгенерирована из деления на ноль снова, который не будет обработан, потому что вы не можете вложить обработку ошибок в другой обработчик ошибок.Поэтому код не имеет смысла в его нынешнем виде, обработчик ошибок должен быть перемещен ниже кода (ниже exit sub), чтобы убедиться, что он только вызывается один раз:
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)
AGoTo error handler это вершина процедуры является хорошим стилем программирования и должно быть минимальным количеством обработки ошибок для большинства процедур. Однако он менее гибок, чем проверка ошибок после строк кода, которые могут вызвать ошибку. При добавлении обработки ошибок в довольно простой процедуре я использую On Error GoTo ... оператор и обработчик ошибок catch-all в нижней части подпрограммы.
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 потому что это делает код трудным для чтения и следования. В процедуре, где я выполняю несколько шагов и хочу вернуть ошибку, которая более точно описывает, где код пошел не так, или в ситуации, когда у меня может быть шанс восстановить ошибку и продолжить, я отключаю тип обработки ошибок catch-all и проверяю 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
Comments