Поделиться через


about_Trap

Краткое описание

Описывает ключевое слово, которое обрабатывает завершающую ошибку.

Длинное описание

Завершающая ошибка останавливает выполнение инструкции. Если PowerShell не обрабатывает завершающую ошибку каким-либо образом, она также прекращает выполнение функции или скрипта в текущем потоке. На других языках, таких как C#, завершающие ошибки называются исключениями.

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

  • Отобразите ошибку после обработки блока инструкций trap и продолжения выполнения скрипта или функции, содержащей trap. Это поведение по умолчанию.

    Заметка

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

  • Отобразите ошибку и прервите выполнение скрипта или функции, содержащей trap, с помощью break в инструкции trap.

  • Замолчать ошибку, но продолжить выполнение скрипта или функции, содержащей trap, с помощью continue в инструкции trap.

Список инструкций trap может включать несколько условий или вызовов функций. trap может записывать журналы, условия тестирования или даже запускать другую программу.

Синтаксис

Оператор trap имеет следующий синтаксис:

trap [[<error type>]] {<statement list>}

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

Сценарий или команда могут содержать несколько операторов trap. операторы trap могут вставляться в любом месте скрипта или команды.

Перехват всех конечных ошибок

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

Следующий пример — это минимальная инструкция trap:

trap { 'Error found.' }

Этот оператор trap улавливает любую завершающую ошибку.

В следующем примере функция содержит бессмысленную строку, которая вызывает ошибку во время выполнения.

function TrapTest {
    trap { 'Error found.' }
    nonsenseString
}

TrapTest

Выполнение этой функции возвращает следующие выходные данные:

Error found.
nonsenseString:
Line |
   3 |      nonsenseString
     |      ~~~~~~~~~~~~~~
     | The term 'nonsenseString' is not recognized as a name of a cmdlet,
function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the
path is correct and try again.

В следующем примере содержится trap инструкция, отображающая ошибку с помощью или $PSItem автоматической переменной$_:

function TrapTest {
    trap { "Error found: $_" }
    nonsenseString
}

TrapTest

Выполнение этой версии функции возвращает следующие выходные данные:

Error found: The term 'nonsenseString' is not recognized as the name of a
cmdlet, function, script file, or operable program. Check the spelling of
the name, or if a path was included, verify that the path is correct and
try again.
nonsenseString:
Line |
   3 |      nonsenseString
     |      ~~~~~~~~~~~~~~
     | The term 'nonsenseString' is not recognized as a name of a cmdlet,
function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the
path is correct and try again.

Важный

trap операторы можно определить в любом месте в заданном блоке скрипта, но всегда применяться ко всем операторам в этом скриптблоке. Во время выполнения trap инструкции в блоке определяются перед выполнением других инструкций. На других языках, таких как JavaScript, это называется подъемом. Это означает, что выражения trap применяются ко всем выражениям в этом блоке, даже если выполнение не продвинулось до точки, в которой они определены. Например, определение trap в конце скрипта и возникновение ошибки в первой инструкции по-прежнему приводит к активации trap.

Перехват конкретных ошибок

Сценарий или команда могут содержать несколько операторов trap. Для обработки определенных ошибок можно определить trap.

В следующем примере показана инструкция trap, которая перехватывает конкретную ошибку CommandNotFoundException:

trap [System.Management.Automation.CommandNotFoundException] {
    'Command error trapped'
}

Если функция или скрипт обнаруживает строку, которая не соответствует известной команде, эта инструкция trap отображает строку Command error trapped. После выполнения списка инструкций trap PowerShell записывает объект ошибки в поток ошибок, а затем продолжает скрипт.

PowerShell использует типы исключений .NET. В следующем примере указывается тип ошибки System.Exception:

trap [System.Exception] { 'An error trapped' }

Тип ошибки CommandNotFoundException наследуется от типа System.Exception. Эта инструкция перехватывает все ошибки, вызванные неизвестными командами. Он также перехватывает другие типы ошибок.

Тип исключения для ошибки можно найти, проверяя объект ошибки. В следующем примере показано, как получить полное имя исключения для последней ошибки в сеансе:

nonsenseString
$Error[0].Exception.GetType().FullName
nonsenseString: The term 'nonsenseString' is not recognized as a name of a
cmdlet, function, script file, or executable program. Check the spelling
of the name, or if a path was included, verify that the path is correct
and try again.

System.Management.Automation.CommandNotFoundException

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

В следующем примере скрипта содержится ошибка. Скрипт содержит общую инструкцию trap, которая перехватывает любую завершающую ошибку, и конкретную инструкцию trap, определяющую тип CommandNotFoundException.

trap { 'Other terminating error trapped' }
trap [System.Management.Automation.CommandNotFoundException] {
  'Command error trapped'
}
nonsenseString

Выполнение этого скрипта приводит к следующему результату:

Command error trapped
nonsenseString:
Line |
   5 |      nonsenseString
     |      ~~~~~~~~~~~~~~
     | The term 'nonsenseString' is not recognized as a name of a cmdlet,
function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the
path is correct and try again.

Так как PowerShell не распознает nonsenseString как командлет или другой элемент, он возвращает ошибку CommandNotFoundException. Конкретная инструкция trap перехватывает эту завершающую ошибку.

В следующем примере скрипта содержатся те же trap утверждения с другой ошибкой.

trap { 'Other terminating error trapped' }
trap [System.Management.Automation.CommandNotFoundException] {
    'Command error trapped'
}
1/$null

Выполнение этого скрипта приводит к следующему результату:

Other terminating error trapped
RuntimeException:
Line |
   5 |  1/$null
     |  ~~~~~~~
     | Attempted to divide by zero.

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

Перехват ошибок в блоке скрипта

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

Например, если в инструкции возникает завершающаяся ошибка, инструкция выполняется foreach и выполнение продолжается в следующей инструкции после trap блока, а не внутри foreach блока.foreach

trap { 'An error occurred!'}
foreach ($x in 3..-1) {
       "1/$x = "
       "`t$(1/$x)"
}
'after loop'
1/3 =
        0.333333333333333
1/2 =
        0.5
1/1 =
        1
1/0 =
An error occurred!
RuntimeException:
Line |
   4 |         "`t$(1/$x)"
     |              ~~~~
     | Attempted to divide by zero.
after loop

В результатах вывода вы можете видеть, что циклы продолжаются до последней итерации. Когда скрипт пытается разделить 1 на 0, PowerShell выдает завершающееся сообщение об ошибке. Скрипт пропускает остальную часть foreach инструкции, выполняет try инструкцию и продолжается после инструкции foreach .

Ошибки и область перехвата

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

Например, если в функции возникает ошибка, а оператор trap находится в функции, скрипт продолжается в следующей инструкции. Следующий скрипт содержит ошибку и инструкцию trap:

function function1 {
    trap { 'An error: ' }
    NonsenseString
    'function1 was completed'
}

function1

Выполнение этого скрипта приводит к следующему результату:

An error:
NonsenseString:
Line |
   3 |      NonsenseString
     |      ~~~~~~~~~~~~~~
     | The term 'NonsenseString' is not recognized as a name of a cmdlet,
function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the
path is correct and try again.
function1 was completed

Оператор trap в функции перехватывает ошибку. После отображения сообщения PowerShell возобновляет выполнение функции. Обратите внимание, что Function1 завершено после инструкции trap.

Сравните это поведение со следующим примером, который имеет ту же ошибку и выражение trap. В этом примере оператор trap находится вне функции.

function function2 {
    NonsenseString
    'function2 was completed'
}

trap { 'An error:' }

function2

Выполнение функции Function2 приводит к следующему результату:

An error:
NonsenseString:
Line |
   2 |      NonsenseString
     |      ~~~~~~~~~~~~~~
     | The term 'NonsenseString' is not recognized as a name of a cmdlet,
function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the
path is correct and try again.

В этом примере команда function2 was completed не выполнялась. В обоих примерах в функции возникает завершающая ошибка. Однако в этом примере оператор trap находится за пределами функции. PowerShell не возвращается в функцию после выполнения инструкции trap.

Осторожность

При определении нескольких перехватов для одного условия ошибки используется первый trap определенный лексически (самый высокий в скрипте).

В следующем примере запускается только trap, а whoops 1 используется для выполнения.

Remove-Item -ErrorAction Stop ThisFileDoesNotExist
trap { 'whoops 1'; continue }
trap { 'whoops 2'; continue }

Важный

Оператор trap ограничен тем, где он компилируется. Если у вас есть оператор trap внутри функции или скрипта с точками, при завершении работы функции или исходного скрипта все trap инструкции внутри удаляются.

Использование ключевых слов break и continue

Ключевые слова break и continue можно использовать в инструкции trap, чтобы определить, продолжает ли скрипт или команда выполняться после завершения ошибки.

Если вы включаете инструкцию break в список инструкций trap, PowerShell останавливает функцию или скрипт. В следующем примере функции используется ключевое слово break в инструкции trap.

function break_example {
    trap {
        'Error trapped'
        break
    }
    1/$null
    'Function completed.'
}

break_example
Error trapped
ParentContainsErrorRecordException:
Line |
   6 |      1/$null
     |      ~~~~~~~
     | Attempted to divide by zero.

Так как инструкция trap включала ключевое слово break, функция не продолжает выполняться, а строка Function completed не выполняется.

Если вы включаете ключевое слово continue в инструкцию trap, PowerShell возобновляется после инструкции, вызвавшей ошибку, так же, как и без break или continue. Однако при использовании ключевого слова continue PowerShell не записывает ошибку в поток ошибок.

В следующем примере функции используется ключевое слово continue в инструкции trap.

function ContinueExample {
    trap {
        'Error trapped'
        continue
    }
    foreach ($x in 3..-1) {
       "1/$x = "
       "`t$(1/$x)"
    }
    'End of function'
}

ContinueExample
1/3 =
        0.333333333333333
1/2 =
        0.5
1/1 =
        1
1/0 =
Error trapped
End of function

Функция возобновляется после того, как ошибка захвачена, и выполняется инструкция End of function. Ошибка не записывается в поток ошибок.

Примечания.

trap операторы предоставляют способ обеспечить обработку всех конечных ошибок в скриптблоке. Для более точной обработки ошибок используйте try/catch блоки, в которых ловушки определяются с помощью catch инструкций. Операторы catch применяются только к коду, находящемуся внутри связанного оператора try. Дополнительные сведения см. в разделе about_Try_Catch_Finally.

См. также