Влияние на скорость при ошибке Resume Next

При условии vbscript не имеет On Error Goto MyLabel вид синтаксиса, как с vbaЯ рассматриваю возможность использования следующих ошибок:

On Error Resume Next

'Do some stuff

If Err.Number <> 0 Then
    Err.Clear
    'Handle the error
End If

'Do some more stuff

If Err.Number <> 0 Then
    Err.Clear
    'Handle the error
End If

'...

Мой вопрос: какое влияние на скорость будет оказывать этот тип техники?

Кроме того, я хотел бы знать, есть ли лучший способ встроить обработку ошибок в vbscript

2 ответа

Решение
  1. Нет смысла сравнивать скорость правильной и ошибочной реализации. Если ваш скрипт не выполняет свои спецификации без обработки ошибок и работает медленно при использовании OERN, вам нужно выбрать другой язык.
  2. Поскольку OERN скрывает ошибки, его область действия должна быть как можно меньше. Ваш пример кода пахнет как использование OERN во всем мире - очень плохая идея. Кроме того: Вам нужно Err.Clear или "On Error GoTo 0" после каждой рискованной операции и соответствующей проверки Err.Number.
  3. В других языках (например, Python) "проще просить прощения, чем разрешения"; из-за плохой природы обработки ошибок VBScript в большинстве случаев вы должны "смотреть перед тем, как прыгнуть", и использовать OERN только тогда, когда это абсолютно неизбежно (например, проверка на наличие ключей реестра, устранение возможных сбоев внешних ресурсов).

Идиома для локальной обработки ошибок:

Dim gaErr ' global error array
...
Sub SomeSub()
    ...
    OERN
    risky op
    gaErr = Array(Err.Number, Err.Description, ...)
    OEG0
    If gaErr(0) Then
       handle error
    ...
End Sub

Если ваши спецификации требуют глобальной обработки ошибок:

Dim gaErr
OERN
ret = main()
gaErr = Array(...)
OEG0
If gaErr(0) Then
   some fatal/not locally handled error occured somewhere in your script
   handle it gracefully
Else
   If ret is bad Then
      deal with this
   Else
      ask for more money
   End If
End If
WScript.Quit good/bad

Function main()
  main = ...
End Function

Обновление с комментарием:

Почему глобальное зловещее зло? Рассматривать:

OERN
(1) Process/change important data
(2) Delete original data - if (1) failed you just destroyed the base of your business

OERN
(1) Process/change important data
(2) If Err.Nunber Then Backup(database, destinatiom)
(3) Continue although the Backup didn't take place, because at least three error were hidden

Кстати: ваше добавление Err.Clear находится не в том месте - вы теряете информацию об ошибке, прежде чем сможете ее обработать.

Обновление по комментарию II:

Рассмотрим этот демонстрационный скрипт:

' dgeh.vbs - demo global error handling

Option Explicit

' globals
Dim gWAN : Set gWAN = WScript.Arguments.Named
Dim gaErr

Dim iRet
' top-level/global OERN starts here (errors before will abort mercylessly)
On Error Resume Next
 iRet  = main() ' not more than two statements!
 gaErr = Array(Err.Number, Err.Description, Err.Source)
On Error GoTo 0
If gaErr(0) Then
   WScript.Echo "Fatal Error:", Join(gaErr, " * ")
   iRet = 1 ' or choose a better number
Else
   If iRet Then
      WScript.Echo "need one of /good, /bad, or /fatal, Mr. User!"
   Else
      WScript.Echo "all's well"
   End If
End If
WScript.Quit iRet

Function main()
  main = 2
  If gWAN.Count = 1 And (gWAN.Exists("good") Or gWAN.Exists("bad") Or gWAN.Exists("fatal")) Then
     readTheDocs
     main = 0
  End If
End Function

Sub readTheDocs()
    WScript.Echo "read Microsoft's Docs"
    If gWAN.Exists("fatal") Then
       caTastrophy
    Else
       trySomethingRisky
    End If
End Sub

Sub trySomethingRisky()
  Dim n
  If gWAN.Exists("bad") Then n = 1 / 0
  WScript.Echo "but be skeptical of the text and your interpretation"
End Sub

Sub caTastrophy()
  On Error Resume Next ' simulating the evil global OERN and not checking *each* statement
     WScript.Echo "saving the world"
     saveTheWorld
     WScript.Echo "deleting the now obsolete original"
  On Error GoTo 0
End Sub

выход для

cscript dgeh.vbs /fatal
read Microsoft's Docs
saving the world
deleting the now obsolete original
all's well
echo %ERRORLEVEL%
0

Поскольку Sub saveTheWorld отсутствует, вы просто устранили обработку ошибок, VBScript и все остальное. Вы даже не можете пообещать никогда больше не использовать злое глобальное OERN, потому что вы - и те сценаристы, которые обычно его используют (и тем самым доказали, что им платят за их шутки, а не их код) - исчезли. Будем надеяться, что вызывающий процесс не примет значение ERRORLEVEL в качестве лицензии для некоторых дальнейших удалений.

выход для

cscript dgeh.vbs
need one of /good, /bad, or /fatal, Mr. User!
echo %ERRORLEVEL%
2

cscript dgeh.vbs /nix
need one of /good, /bad, or /fatal, Mr. User!

cscript dgeh.vbs /fatal /bad
need one of /good, /bad, or /fatal, Mr. User!

продемонстрировать стратегию "посмотри, прежде чем прыгать".

вывод для хорошего случая:

cscript dgeh.vbs /good
read Microsoft's Docs
but be skeptical of the text and your interpretation
all's well
echo %ERRORLEVEL%
0

оба сообщения показаны (и это справедливо).

а теперь что-то совсем другое:

cscript dgeh.vbs /bad
read Microsoft's Docs
Fatal Error: 11 * Division by zero * Microsoft VBScript runtime error
echo %ERRORLEVEL%
1

Пожалуйста отметьте отсутствие второго сообщения. Деление на ноль приведет к выполнению следующей строки в активной области OERN (сохранение в gaErr) и не будет продолжаться вслепую / бездумно. Рискованная операция (выполняющая то, что делают main() и все ее дочерние элементы) затем проверяется (через прокси-сервер gaErr). Это соблюдает правило "не более двух строк (рискованно и сохраняя информацию об ошибках) в пределах OERN".

Цена за такую ​​глобальную обработку ошибок: вы теряете информацию о номере строки - изящно справляться с ошибкой становится сложнее.

Но поскольку в вашем сценарии есть только одно OERN (с этого момента в ваших программах не будет Sub caTastrophy()), вы можете закомментировать его во время разработки и отладки.

вывод с OERN закомментирован:

cscript dgeh.vbs /bad
read Microsoft's Docs
E:\trials\SoTrials\answers\21901890\vbs\dgeh.vbs(46, 30) Microsoft VBScript runtime error: Division by zero

Когда я использую обработку ошибок в Vbscript, я не нахожу, что это имеет проблему с производительностью. Однако в моих программах это обычно делает что-то довольно простое, например, вывод оператора Failed в файл журнала. wscript.quitтак что я никогда не находил это для снижения производительности системы. На приведенном вами примере обычно добавляется On Error Goto 0 после последнего End If где вы проверяете на ошибку. Это может привести к тому, что ошибка не будет сброшена, поэтому при следующем выполнении проверки она будет по-прежнему неправильно сохранять старое значение ошибки.

Другие вопросы по тегам