VBScript - Використання обробки помилок


84

Я хочу використовувати VBScript для лову помилок та їх реєстрації (тобто при помилці "щось записати"), а потім відновити наступний рядок сценарію.

Наприклад,

Про помилку Поновити далі
'Виконайте крок 1
'Виконайте крок 2
'Виконайте крок 3

Коли на кроці 1 виникає помилка, я хочу, щоб ця помилка реєструвалась (або виконувала з нею інші користувацькі функції), а потім відновлювалась на кроці 2. Чи можливо це? і як я можу це реалізувати?

EDIT: Чи можу я зробити щось подібне?

Про помилку Відновити myErrCatch
'Виконайте крок 1
'Виконайте крок 2
'Виконайте крок 3

myErrCatch:
'помилка журналу
Поновити далі

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

Відповіді:


161

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 for Applications (VBA), але VBScript не підтримує цю мовну функцію, тому вам доведеться використовувати On Error Resume Next, як описано вище.


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

msgstr "містить повторні результати останньої виконаної операції". Це правда? Здається, він отримує останню помилку, що є великою різницею.
Damien Golding

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

@ user66001 Погодився, але все ж безпечніше чітко дзвонити Err.Clear.
Ланкімарт,

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
Не найяскравіший приклад, який я коли-небудь бачив, але я розумію концепцію.
Ланкімарт,

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

3
На секунду у мене склалося враження, що я пропустив нову парадигму програмного забезпечення під назвою "omegastripes" ха-ха
TheBlastOne

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, не звичайний старий VBScript
Jobbo
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.