Обработка исключений


Чеботарев Игорь

Вначале стоит определиться с терминами, ведь если любой программист прекрасно знает что такое "исключения", то остальные далеко не все точно представляют о чем идет речь. Говоря простым языком исключения или исключительные ситуации - это ошибки, возникающие в ходе работы программы (в нашем случае скрипта). Но это не те ошибки, когда вы забыли поставить закрывающую скобку, запятую или ошиблись в имени переменной. Это ошибки, возникающие в некоторых (исключительных) ситуациях во время выполнения РАБОЧЕГО скрипта.

Рассмотрим простенький пример скрипта на VBScript, пытающегося прочитать значение какого-то параметра в реестре и выдать его в сообщении:

Dim Perem 
set WSHShell = WScript.CreateObject("WScript.Shell") 
WSHShell.Popup "Начало скрипта" 

Perem = WSHShell.RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Test") 

WSHShell.Popup Perem 
WSHShell.Popup "Конец скрипта"

Сообщение "Начало скрипта" появилось, следовательно, синтаксических ошибок мы не допустили, но вот затем появляется сообщение об ошибке

Пример сообщения об ошибке

что и неудивительно - параметра с именем Test в разделе HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer не существует. Из-за этого наш пример не отработал до конца. Возникает логичный вопрос: а нельзя ли каким-то образом отловить момент появления ошибки, как-то его обработать и продолжить выполнение скрипта дальше? Оказывается, можно. Перепишем наш пример следующим образом:

Dim Perem 
set WSHShell = WScript.CreateObject("WScript.Shell") 
WSHShell.Popup "Начало скрипта" 
On Error Resume Next 
GetErr() 

if Err.Source="WshShell.RegRead" then 
   Perem = "Параметр не существует" 
else 
   Perem = WSHShell.RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Test") 
end if 

Err.Clear 
WSHShell.Popup Perem 
WSHShell.Popup "Конец скрипта" 

Function GetErr() 
   If WSHShell.RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Test") Then 
   End If 
End Function

Попытка прочитать параметр из реестра вынесена в отдельную функцию. Если происходит ошибка - функция возвращает код ошибки (Err.Number) и источник (Err.Source). В операторе if мы проверяем та ли это ошибка, что нам нужна и если это именно так, значит параметр не удалось прочитать по причине его отсутствия, о чем нас честно и предупреждают в появившемся сообщении. При этом скрипт корректно отрабатывает до конца. Если же ошибки не возникло, мы спокойно прочитываем значение нужного нам параметра.

Обратите внимание на объект Err. Это стандартный объект VBScript, содержащий информацию о так называемых run-time errors (ошибках времени выполнения). Свойство Source указывает на источник ошибки (в сообщении на рисунке это последняя строка). Метод Clear очищает свойства объекта, удаляя сведения об ошибке. Помимо Source и Clear у объекта есть и другие свойства и методы, но реально может понадобиться, пожалуй, свойство Number и Description. Number возвращает код произошедшей ошибки, а Description ее описание. Измените в скрипте строку

Perem = "Параметр не существует"

на

Perem = "Ошибка " & Err.Number & ". " Err.Description

Во время выполнения скрипта появится сообщение: "Ошибка -2147024894. Не удается открыть для чтения раздел реестра "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Test"". Это большое отрицательное число и есть код ошибки. При обработке исключений можно пользоваться и номерами ошибок.

Почему для объяснения работы с исключениями я объяснял все примеры на чтении данных из реестра? Во-первых, работа с реестром в WSH одна из наиболее часто встречаемых задач, во-вторых, другие ошибки (например, попытка подмапировать сетевой диск на уже существующую букву, попытка открытия несуществующего файла и т.п.) могут быть обработаны другими способами (при открытии файла можно сперва проверить его наличие с помощью метода FileExists объекта fso), в то время как проверка наличия какого-либо параметра в реестре отсутствует в принципе. Поэтому вопросы обработки исключений при работе с реестром наиболее актуальны.

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

читать еще по теме