VBScript - Использование обработки ошибок


86

Я хочу использовать VBScript, чтобы перехватывать ошибки и регистрировать их (т.е. при ошибке «записывать что-то»), а затем возобновить следующую строку скрипта.

Например,

При ошибке Возобновить Далее
'Сделайте шаг 1
'Сделайте шаг 2
'Сделайте шаг 3

Когда ошибка возникает на шаге 1, я хочу, чтобы он регистрировал эту ошибку (или выполнял с ней другие настраиваемые функции), а затем возобновлял работу на шаге 2. Возможно ли это? и как я могу это реализовать?

РЕДАКТИРОВАТЬ: Могу я сделать что-то подобное?

При ошибке возобновить myErrCatch
'Сделайте шаг 1
'Сделайте шаг 2
'Сделайте шаг 3

myErrCatch:
'ошибка журнала
Продолжить Далее

1
Ответ Дилана примерно такой же, как у VB в отделе обработки ошибок. Вот почему я всегда использовал Javascript, когда это могло сойти с рук.
wcm, 01

Ответы:


163

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

On Error Resume Next

DoStep1

If Err.Number <> 0 Then
  WScript.Echo "Error in DoStep1: " & Err.Description
  Err.Clear
End If

DoStep2

If Err.Number <> 0 Then
  WScript.Echo "Error in DoStop2:" & Err.Description
  Err.Clear
End If

'If you no longer want to continue following an error after that block's completed,
'call this.
On Error Goto 0

Синтаксис «On Error Goto [label]» поддерживается Visual Basic и Visual Basic для приложений (VBA), но VBScript не поддерживает эту языковую функцию, поэтому вы должны использовать On Error Resume Next, как описано выше.


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

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

Несмотря на то, что документация MS предполагает, что это err.clearнеобходимо использовать после каждой проверки объекта, чтобы предотвратить предыдущие ошибки, приводящие к срабатыванию следующей проверки (например, technet.microsoft.com/en-us/library/ee692852.aspx ), по моему опыту errочищается " сам по себе "по мере выполнения сценария. Без дальнейшего тестирования я предполагаю, что очистка объектов используется errкак побочный продукт их внутренних операций.
user66001 02

@ user66001 Согласен, но все же безопаснее явно звонить Err.Clear.
user692942

12

Обратите внимание, что On Error Resume Nextэто не установлено глобально. Вы можете поместить небезопасную часть кода, например, в функцию, которая будет немедленно прервана в случае возникновения ошибки, и вызвать эту функцию из подпрограммы, содержащей предыдущий OERNоператор.

ErrCatch()

Sub ErrCatch()
    Dim Res, CurrentStep

    On Error Resume Next

    Res = UnSafeCode(20, CurrentStep)
    MsgBox "ErrStep " & CurrentStep & vbCrLf & Err.Description

End Sub

Function UnSafeCode(Arg, ErrStep)

    ErrStep = 1
    UnSafeCode = 1 / (Arg - 10)

    ErrStep = 2
    UnSafeCode = 1 / (Arg - 20)

    ErrStep = 3
    UnSafeCode = 1 / (Arg - 30)

    ErrStep = 0
End Function

1
Не самый ясный пример, который я когда-либо видел, но я понимаю концепцию.
user692942

7
@Lankymart, не могли бы вы привести более ясный пример, который вы видели тогда, или вместо этого предложите, как омегастрипы могут улучшить этот пример?
Доминик

3
На секунду у меня создалось впечатление, что я пропустил новую парадигму разработки программного обеспечения под названием «omegastripes»,
смеется

4

Вы можете перегруппировать вызовы функций шагов в функции фасада:

sub facade()
    call step1()
    call step2()
    call step3()
    call step4()
    call step5()
end sub

Затем позвольте вашей обработке ошибок быть в верхней функции, которая вызывает фасад:

sub main()
    On error resume next

    call facade()

    If Err.Number <> 0 Then
        ' MsgBox or whatever. You may want to display or log your error there
        msgbox Err.Description
        Err.Clear
    End If

    On Error Goto 0
end sub

Теперь предположим, что step3()возникает ошибка. Так как facade()не обрабатывают ошибки (нет нет On error resume next в facade()), то ошибка будет возвращена main()и step4()и step5()не будет выполнена.

Обработка ошибок теперь переработана в 1 блоке кода.


1

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

Dim oConn, connStr
Set oConn = Server.CreateObject("ADODB.Connection")
connStr = "Provider=SQLOLEDB;Server=XX;UID=XX;PWD=XX;Databse=XX"

ON ERROR RESUME NEXT

oConn.Open connStr
If err.Number <> 0 Then : showError() : End If


Sub ShowError()

    'You could write the error details to the console...
    errDetail = "<script>" & _
    "console.log('Description: " & err.Description & "');" & _
    "console.log('Error number: " & err.Number & "');" & _
    "console.log('Error source: " & err.Source & "');" & _
    "</script>"

    Response.Write(errDetail)       

    '...you could display the error info directly in the page...
    Response.Write("Error Description: " & err.Description)
    Response.Write("Error Source: " & err.Source)
    Response.Write("Error Number: " & err.Number)

    '...or you could execute additional code when an error is thrown...
    'Insert error handling code here

    err.clear
End Sub

1
Это ASP Classic, а не старый
добрый
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.