Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Краткое описание
Описывает типы ошибок в PowerShell и механизмы их обработки.
Длинное описание
PowerShell различает три категории ошибок:
- Неустранимые ошибки
- Завершающие инструкции ошибки
- Завершающие ошибки скрипта
Понимание различия является важным для написания надежных скриптов и модулей, так как каждая категория имеет разные поведение по умолчанию и требует различных методов обработки.
Кроме того, внешние (собственные) программы сообщают о сбое через коды выхода, которые PowerShell отслеживает отдельно от собственной системы ошибок.
Типы ошибок
Неустранимые ошибки
Неустранимая ошибка сообщает о проблеме, но не останавливает конвейер. Команда продолжает обрабатывать последующие входные объекты. Неустранимые ошибки создаются следующими:
-
Write-ErrorКомандлет -
$PSCmdlet.WriteError()Метод в расширенных функциях - Командлеты, которые сталкиваются с восстанавливаемыми сбоями в отдельных входных объектах
По умолчанию PowerShell отображает сообщение об ошибке и продолжает выполнение.
# Non-terminating error: the pipeline continues after the failure
'file1.txt', 'noSuchFile.txt', 'file3.txt' | ForEach-Object {
Get-Content $_ -ErrorAction Continue
}
В этом примере Get-Content сообщает об ошибке noSuchFile.txt , не завершающейся, а затем продолжает обработку file3.txt.
Неисключающие ошибки не активируются catch или trap по умолчанию.
Завершающие инструкции ошибки
После завершения инструкции ошибка останавливает выполнение текущей инструкции (конвейера), но выполнение продолжается на следующей инструкции в скрипте. Завершающие инструкции ошибки создаются следующими:
-
$PSCmdlet.ThrowTerminatingError()Метод в расширенных функциях и скомпилированных командлетах - Ошибки подсистемы, такие как
CommandNotFoundException(вызов команды, которая не существует) иParameterBindingException(недопустимые аргументы параметров) - Вызовы метода .NET, которые вызывают исключения, например
[int]::Parse('abc')
# Statement-terminating error: Get-Item fails, but the next statement runs
Get-Item -Path 'C:\NoSuchFile.txt'
Write-Output 'This still runs'
Завершающие инструкции ошибки могут быть пойманы try/catch и trap.
Замечание
.ThrowTerminatingError() не обращается к параметру -ErrorAction (за исключением Break значения, которое вводит отладчик).
$ErrorActionPreference Однако применяется к завершающим ошибкам операторов через обработчик уровня инструкции обработчика. Например, может подавлять завершающуюся ошибку оператора, $ErrorActionPreference = 'SilentlyContinue' чтобы скрипт продолжался в следующей инструкции. Этот -ErrorAction параметр не может сделать. Дополнительные сведения см. в разделе "Асимметрия $ErrorActionPreference".
Завершающие ошибки скрипта
Завершающаяся ошибка скрипта удаляет весь стек вызовов. Выполнение останавливается полностью, если ошибка не перехватывается блоком или try/catch операторомtrap. Завершающие скрипты ошибки создаются следующими:
- Ключевое слово
throw - Синтаксические ошибки анализа (синтаксические ошибки, которые препятствуют компиляции скрипта)
- Неустранимые ошибки , вызванные
-ErrorAction Stopили$ErrorActionPreference = 'Stop'неоконцентными контекстами. Дополнительные сведения см. в разделе "Как работает эскалация". - Некоторые критические сбои двигателя
# Script-terminating error: throw unwinds the call stack
function Test-Throw {
throw 'Critical failure'
Write-Output 'This never runs'
}
Test-Throw
Write-Output 'This never runs either (unless caught)'
Ключевое throw слово по умолчанию создает ошибку, завершающая скрипт. Однако $ErrorActionPreference подавляться, throw если задано SilentlyContinue значение или Ignore. При вызове расширенной функции с -ErrorAction SilentlyContinueпараметром преобразуется в локальное $ErrorActionPreference значение области, поэтому он также подавляет throw внутри этой функции.
Замечание
Даже с $ErrorActionPreference = 'Ignore'тем, что throw этот параметр все еще записывает запись в $Error. Значение Ignore запрещает $Error запись только для неисключающих ошибок.
Это важно
Термины , завершающие и завершающиескрипт , описывают область влияния, а не серьезность ошибки. Завершающаяся ошибка оператора останавливает одну инструкцию. Завершающаяся ошибка скрипта останавливает весь скрипт и его вызывающие. Оба могут быть пойманы try/catch.
Ошибки внешней программы
Внешние (собственные) программы не участвуют непосредственно в системе ошибок PowerShell. Они сообщают о сбое с помощью кода выхода, отличного от нуля, который PowerShell хранит в автоматической переменной $LASTEXITCODE .
git clone https://example.com/nonexistent.git 2>$null
if ($LASTEXITCODE -ne 0) {
Write-Error "git failed with exit code $LASTEXITCODE"
}
По умолчанию код выхода без нуля из собственной программы:
- Задает значение
$?$false -
Не создает вход
ErrorRecord$Error - Не активирует или не активирует
catchtrap
PowerShell 7.3 добавила экспериментальную переменную $PSNativeCommandUseErrorActionPreferenceпредпочтения, которая стала стабильной функцией в версии 7.4. При установке этой переменной это значение $trueвызывает ненулевой код выхода, который выдает неисключаемую ошибку , сообщение которой указывает конкретный код выхода (a NativeCommandExitException). Эта ошибка учитывается $ErrorActionPreferenceтаким образом, чтобы задать ее для Stop распространения ошибки на завершающую ошибку скрипта, с помощью которую можно пойматьtry/catch.
Переменные состояния ошибки
PowerShell поддерживает несколько автоматических переменных, которые отражают текущее состояние ошибки.
$?
Содержит, $true если последняя операция завершилась успешно, и $false если она вызвала какую-либо ошибку (не завершающаяся или завершающаяся). Для собственных $? команд устанавливается на основе кода выхода: $true для кода 0выхода, $false в противном случае.
Get-Item -Path 'C:\NoSuchFile.txt' 2>$null
$? # False
$Error
Объект ArrayList , в который хранятся последние записи об ошибках, с последней ошибкой по индексу 0. Список содержит до $MaximumErrorCount записей (по умолчанию 256).
Все конечные ошибки добавляются в $Error. Для прекращения ошибок отключает отображение, Ignore но по-прежнему записывает ошибку $Error. Все неустранимые добавляются $Error , если -ErrorAction Ignore не используется для неисключающих ошибок, что предотвращает отображение и запись.
$LASTEXITCODE
Содержит код выхода последней запущенной собственной программы. Значение 0 обычно указывает на успешность. Любое ненулевое значение указывает на сбой. Эта переменная не влияет на ошибки командлетов PowerShell.
Управление поведением ошибки
Общий -ErrorAction параметр
Общие -ErrorAction параметры переопределяются $ErrorActionPreference для одной команды. Он определяет, как PowerShell реагирует на неисключающие ошибки из этой команды.
| Ценность | Поведение |
|---|---|
Continue |
Отображение ошибки и продолжение (по умолчанию) |
SilentlyContinue |
Отключить отображение, добавить в $Error, продолжить |
Ignore |
Отключение отображения и не добавление в $Error |
Stop |
Эскалация до конца ошибки (см. инструкции по эскалации) |
Inquire |
Запрос пользователя на принятие решения |
Break |
Введите отладчик |
-ErrorAction не изменяет поведение ошибок, $PSCmdlet.ThrowTerminatingError()создаваемых . Эти ошибки всегда завершаются оператором независимо от предпочтений вызывающего объекта.
Переменная $ErrorActionPreference
Переменная $ErrorActionPreference предпочтения применяется ко всем командам в текущей области и дочерних областях. Он принимает те же значения, что -ErrorActionи .
$ErrorActionPreference = 'Stop'
# All non-terminating errors in this scope now become terminating
Write-Error 'This now throws' # Generates ActionPreferenceStopException
Если -ErrorAction задано в команде, она имеет приоритет $ErrorActionPreference над этой командой.
Как работает эскалация
Если -ErrorAction Stop или $ErrorActionPreference = 'Stop' в действительности, PowerShell преобразует неисключающие ошибки в завершающие ошибки с помощью следующего механизма:
- Командлет вызывает
WriteError()внутреннее сообщение об ошибке, не завершающейся. - Модуль проверяет действующие
ErrorActionпредпочтения команды. - Так как предпочтительный параметр,
Stopподсистема создаетActionPreferenceStopExceptionисходную запись об ошибке. - Если вы поймали
catch, исходная информация об ошибке доступна через$_.Exception.ErrorRecord.
Область эскалации ошибки зависит от контекста:
- В не расширенных сценариях, функциях или блоках скриптов параметр
$ErrorActionPreference = 'Stop'преобразуется в ошибку , завершающая скрипт . Ошибка распространяется на стек вызовов. - В расширенных функциях и блоках скриптов (с
[CmdletBinding()]) ошибка остается завершающим оператором. Выполнение продолжается в следующей инструкции после вызова. - Передача
-ErrorAction Stopв расширенную функцию имеет тот же эффект, что и настройка$ErrorActionPreference = 'Stop'внутри нее, так как-ErrorActionпреобразуется в локальное$ErrorActionPreferenceзначение области.
Примеры эскалации
NON-advanced: завершение скрипта ("after" не печатается)
& { param() $ErrorActionPreference = 'Stop' 1/0 # Divide by zero error } 2>$null 'after'ADVANCED: завершение инструкции ("after" ВЫПОЛНЯЕТ печать)
& { [CmdletBinding()] param() $ErrorActionPreference = 'Stop' 1/0 # Divide by zero error } 2>$null 'after'Без
-ErrorAction Stop: без конца, catch не выполняетсяtry { Write-Error 'This is non-terminating' Write-Output 'Execution continues' } catch { Write-Output "Caught: $_" # Not reached }С :
-ErrorAction Stopпереросло на завершениеtry { Write-Error 'This becomes terminating' -ErrorAction Stop } catch { Write-Output "Caught: $_" # Reached }
Перераскрытые ошибки могут быть пойманы по исходному типу исключений. Подсистема распаковывает ActionPreferenceStopException базовое исключение:
try {
Get-Item -Path 'C:\NoSuchFile.txt' -ErrorAction Stop
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Output "File not found: $($_.Exception.Message)"
}
$ErrorActionPreference Асимметрия
Параметр -ErrorAction и $ErrorActionPreference переменная ведут себя по-разному с ошибками конца. Важно понимать эту асимметрию:
-ErrorActionвлияет только на неустранимые ошибки. При вызове$PSCmdlet.ThrowTerminatingError()-ErrorActionкомандлета параметр игнорируется (за исключениемBreakтого, что входит в отладчик). Ошибка всегда возникает.$ErrorActionPreferenceвлияет как на завершающие, так и завершающие инструкции ошибки. Обработчик ошибок уровня инструкции считывает$ErrorActionPreference(не-ErrorActionпараметр) и может подавлять завершающееся сообщение об ошибке при значенииSilentlyContinueилиIgnore.
function Test-Asymmetry {
[CmdletBinding()]
param()
$er = [System.Management.Automation.ErrorRecord]::new(
[System.InvalidOperationException]::new('test error'),
'TestError',
[System.Management.Automation.ErrorCategory]::InvalidOperation,
$null
)
$PSCmdlet.ThrowTerminatingError($er)
}
# -ErrorAction SilentlyContinue does NOT suppress the error:
Test-Asymmetry -ErrorAction SilentlyContinue # Error is still thrown
# $ErrorActionPreference DOES suppress the error:
$ErrorActionPreference = 'SilentlyContinue'
Test-Asymmetry # Error is silently suppressed, script continues
$ErrorActionPreference = 'Continue'
Это важно
$ErrorActionPreference Не удается отключить ошибки, для которых задано SuppressPromptInInterpreter значение true. Они всегда распространяются независимо от переменной предпочтения. Ниже приведены примеры ошибки этого типа:
-
ActionPreferenceStopExceptionот-ErrorAction Stopэскалации - Ошибки в методах класса PowerShell
PipelineStoppedException
Управление ошибками
try/catch/finally
Используется try/catch/finally для обработки завершающих инструкций и завершающихся сценарием ошибок. При возникновении ошибки в блоке try PowerShell выполняет поиск соответствующего catch блока. Блок finally всегда выполняется независимо от того, произошла ли ошибка.
try {
$result = Get-Content -Path 'data.txt' -ErrorAction Stop
}
catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning 'Data file not found, using defaults.'
$result = 'default'
}
catch {
Write-Warning "Unexpected error: $_"
}
finally {
Write-Verbose 'Cleanup complete.' -Verbose
}
try Внутри блока подсистема задает внутренний флаг, который приводит к неисключающим ошибкам, вызванным -ErrorAction Stop эскалацией или $ErrorActionPreference = 'Stop' распространением в catch блок. Это разработано поведение, а не особый случай.
Полные сведения о синтаксисе см. в about_Try_Catch_Finally.
trap
Оператор trap обрабатывает завершающие ошибки на уровне области. При возникновении ошибки в любой точке включающей области trap блок выполняется.
-
По умолчанию (нет
breakилиcontinue): отображается ошибка, и выполнение продолжается в следующей инструкции после ошибки. -
continueв ловушке: подавляет сообщение об ошибке и возобновляет работу в следующей инструкции. -
breakв ловушке: ошибка распространяется на родительскую область.
trap [System.Management.Automation.CommandNotFoundException] {
Write-Warning "Command not found: $($_.TargetObject)"
continue
}
NonsenseCommand # Trap fires, execution continues
Write-Output 'This runs because the trap used continue'
Полные сведения о синтаксисе см. в about_Trap.
Создание отчетов об ошибках в функциях и сценариях
При написании функций и скриптов выберите механизм создания отчетов об ошибках, соответствующий серьезности сбоя.
Без конца — использование Write-Error
Используется Write-Error , когда функция может продолжить обработку других входных данных. Это подходит для функций конвейера, которые обрабатывают несколько объектов и сталкиваются с ошибками в отдельных элементах.
function Test-Path-Safe {
[CmdletBinding()]
param([Parameter(ValueFromPipeline)][string]$Path)
process {
if (-not (Test-Path $Path)) {
Write-Error "Path not found: $Path"
return
}
$Path
}
}
Замечание
В расширенных функциях (с [CmdletBinding()]) используйте $PSCmdlet.WriteError() вместо Write-Error того, чтобы убедиться, что $? он правильно задан $false в области вызывающего объекта. Командлет Write-Error не всегда задан $? правильно.
Завершение инструкции — использование $PSCmdlet.ThrowTerminatingError()
Используйте $PSCmdlet.ThrowTerminatingError() , когда функция не может продолжаться вообще, но вызывающий должен решить, как обработать сбой. Это рекомендуемый подход в расширенных функциях.
function Get-Config {
[CmdletBinding()]
param([string]$Path)
if (-not (Test-Path $Path)) {
$er = [System.Management.Automation.ErrorRecord]::new(
[System.IO.FileNotFoundException]::new("Config file not found: $Path"),
'ConfigNotFound',
[System.Management.Automation.ErrorCategory]::ObjectNotFound,
$Path
)
$PSCmdlet.ThrowTerminatingError($er)
}
Get-Content $Path | ConvertFrom-Json
}
После того как ошибка покидает функцию, вызывающий объект обрабатывает его как неисключаемую ошибку по умолчанию. Вызывающий объект может перерасти его с -ErrorAction Stopпомощью .
Завершение скрипта — использование throw
Используйте throw , если восстановление невозможно, и весь скрипт должен остановиться.
$config = Get-Content 'config.json' -ErrorAction SilentlyContinue |
ConvertFrom-Json
if (-not $config) {
throw 'Cannot proceed without a valid configuration file.'
}
Какой механизм следует использовать
- При обработке нескольких входных данных, в которых некоторые могут завершиться ошибкой, использовать
Write-Errorили$PSCmdlet.WriteError(). - Если функция не может продолжаться, используйте
$PSCmdlet.ThrowTerminatingError()и позвольте вызывающему объекту решить, как его обрабатывать. - Если весь скрипт должен немедленно остановиться, используйте
throw.
Сводка типов ошибок
В следующих таблицах приведены сведения о свойствах и поведении различных типов ошибок в PowerShell.
Неисключающая ошибка
Неустранимые ошибки можно создать Write-Error или $PSCmdlet.WriteError().
| Атрибут | Описание |
|---|---|
| Область воздействия | Конвейер продолжается |
Поймали catch |
Нет (если только не перераспределено) |
Поймали trap |
Нет (если только не перераспределено) |
Добавлено в $Error |
Да (если Ignoreне ) |
Задает значение $?$false |
Да |
Затронуты -ErrorAction |
Да |
Затронуты $ErrorActionPreference |
Да |
Ошибка конца инструкции
Завершающие инструкции ошибки могут создаваться с помощью ThrowTerminatingError()ошибок подсистемы, исключений методов .NET или -ErrorAction Stop в расширенных контекстах.
| Атрибут | Описание |
|---|---|
| Область воздействия | Текущая инструкция останавливается; Скрипт продолжается |
Поймали catch |
Да |
Поймали trap |
Да |
Добавлено в $Error |
Да |
Задает значение $?$false |
Да |
Затронуты -ErrorAction |
Нет (Break только) |
Затронуты $ErrorActionPreference |
Да (может подавлять) |
Ошибка прекращения скрипта
Завершающие скрипты ошибки могут создаваться с помощью throwошибок синтаксического анализа или -ErrorAction Stop в не расширенных контекстах.
| Атрибут | Описание |
|---|---|
| Область воздействия | Отмена стека вызовов |
Поймали catch |
Да |
Поймали trap |
Да |
Добавлено в $Error |
Да |
Задает значение $?$false |
Да |
Затронуты -ErrorAction |
Нет |
Затронуты $ErrorActionPreference |
throw: Да (может подавлять) |
Затронуты $ErrorActionPreference |
Эскалация: зависит от контекста |
См. также
PowerShell