VBScript - usando tratamento de erros

86

Quero usar o VBScript para detectar erros e registrá-los (ou seja, em caso de erro "registrar algo") e, em seguida, retomar a próxima linha do script.

Por exemplo,

On Error Resume Next
'Faça o Passo 1
'Faça o Passo 2
'Faça o Passo 3

Quando ocorre um erro na etapa 1, quero que ele registre esse erro (ou execute outras funções personalizadas com ele) e continue na etapa 2. Isso é possível? e como posso implementá-lo?

EDIT: Posso fazer algo assim?

Em caso de erro, Resume myErrCatch
'Faça o passo 1
'Faça o passo 2
'Faça o passo 3

myErrCatch:
'log de erro
Retomar a seguir
apandit
fonte
1
A resposta de Dylan é quase tão boa quanto VB consegue no departamento de tratamento de erros. É por isso que sempre usei Javascript quando podia me safar.
wcm

Respostas:

163

O VBScript não tem noção de lançar ou capturar exceções, mas o tempo de execução fornece um objeto Err global que contém os resultados da última operação executada. Você deve verificar explicitamente se a propriedade Err.Number é diferente de zero após cada operação.

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

A sintaxe "On Error Goto [rótulo]" é suportada pelo Visual Basic e Visual Basic for Applications (VBA), mas o VBScript não oferece suporte a esse recurso de linguagem, portanto, você deve usar On Error Resume Next conforme descrito acima.

Dylan Beattie
fonte
3
Você poderia alterar WScript.Echo dentro da instrução If para chamar uma Função ou Sub, o que poderia, por sua vez, sair do aplicativo, registrar o erro, etc.
StormPooper
"contém os restos da última operação realizada". Isso é verdade? Parece que obtém o último erro, o que é uma grande diferença.
Damien Golding
Apesar da documentação da MS sugerir que err.clearprecisa ser usado após cada verificação do objeto, para evitar erros anteriores que acionem a próxima verificação (por exemplo, technet.microsoft.com/en-us/library/ee692852.aspx ), em minha experiência errestá desmarcada " por si só "à medida que o script avança. Sem testar mais, meu palpite é que utiliza limpezas de objetos errcomo um subproduto de suas operações internas.
user66001
@ user66001 Aceito, mas ainda é mais seguro chamar explicitamente Err.Clear.
user692942
12

Observe que On Error Resume Nextnão é definido globalmente. Você pode colocar sua parte insegura do código, por exemplo, em uma função, que será interrompida imediatamente se ocorrer um erro, e chamar essa função a partir de sub contendo a OERNinstrução precedente .

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
omegastripes
fonte
1
Não é o exemplo mais claro que já vi, mas entendi o conceito.
user692942,
7
@Lankymart, você se importaria de vincular um exemplo mais claro que já viu ou, em vez disso, sugerir como o omegastripes pode melhorar esse exemplo?
Dominick
3
Por um segundo, tive a impressão de que perdi um novo paradigma de engenharia de software chamado "omegastripes" lol
TheBlastOne
4

Você pode reagrupar suas chamadas de funções de etapas em uma função de fachada:

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

Então, deixe seu tratamento de erros estar em uma função superior que chama a fachada:

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

Agora, vamos supor que step3()gere um erro. Desde facade()não manipula erros (há nenhum On error resume next em facade()), o erro será devolvido para main()e step4()e step5()não será executado.

Seu tratamento de erros agora é refatorado em 1 bloco de código

Cid
fonte
1

Sou excepcionalmente novo em VBScript, então isso pode não ser considerado a prática recomendada ou pode haver um motivo para não ser feito dessa forma que eu ainda não conheço, mas esta é a solução que eu encontrei para aparar para baixo a quantidade de código de log de erro no meu bloco de código principal.

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
MistyDawn
fonte
1
Este é o ASP Classic, não o VBScript
Jobbo