about_Trap
简短说明
描述处理终止错误的关键字 (keyword) 。
长说明
终止错误会阻止语句运行。 如果 PowerShell 不以某种方式处理终止错误,PowerShell 也会停止在当前管道中运行函数或脚本。 在其他语言(如 C#)中,终止错误称为异常。
trap
关键字 (keyword) 指定发生终止错误时要运行的语句列表。 trap
语句可以通过以下方式处理终止错误:
在处理
trap
语句块并继续执行包含trap
的脚本或函数后显示错误。 这是默认行为。注意
当从属脚本块(如
if
语句或foreach
循环)中发生终止错误时,将运行块trap
中的语句,并在从属脚本块外的下一个语句继续执行。在 语句中
trap
显示包含trap
break
的脚本或函数的错误和中止执行。使错误保持静音,但通过在 语句中使用
continue
trap
继续执行包含trap
的脚本或函数。
的 trap
语句列表可以包含多个条件或函数调用。 trap
可以写入日志、测试条件,甚至运行其他程序。
语法
trap
语句具有以下语法:
trap [[<error type>]] {<statement list>}
语句 trap
包含发生终止错误时要运行的语句列表。 语句trap
由关键字 (keyword) (可选)后跟类型表达式和语句块(包含捕获错误时要运行的语句列表)组成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 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.
以下示例包含一个 trap
语句,该语句使用 $_
自动变量显示错误:
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 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.
重要
trap
语句可以在给定范围内的任何位置定义,但始终应用于该范围中的所有语句。 在运行时, trap
在执行任何其他语句之前定义 块中的语句。 在 JavaScript 中,这称为 提升。 这意味着, trap
即使执行尚未超过定义这些语句的点,语句也适用于该块中的所有语句。 例如,在 trap
脚本末尾定义 并在第一个语句中引发错误仍会触发该 trap
。
捕获特定错误
一个脚本或命令可以有多个 trap
语句。 trap
可以定义 以处理特定错误。
以下示例是捕获 trap
特定错误 CommandNotFoundException 的语句:
trap [System.Management.Automation.CommandNotFoundException]
{"Command error trapped"}
当函数或脚本遇到与已知命令不匹配的字符串时,此 trap
语句将显示“命令错误捕获”字符串。
运行 trap
语句列表后,PowerShell 将错误对象写入错误流,然后继续脚本。
PowerShell 使用 .NET 异常类型。 以下示例指定 System.Exception 错误类型:
trap [System.Exception] {"An error trapped"}
CommandNotFoundException 错误类型继承自 System.Exception 类型。 此语句捕获未知命令创建的错误。 它还捕获其他错误类型。
一个脚本中可以有多个 trap
语句。 每个错误类型只能由一个 trap
语句捕获。 发生终止错误时,PowerShell 从当前执行范围开始搜索 trap
具有最具体匹配项的 。
以下脚本示例包含错误。 该脚本包括捕获任何终止错误的常规trap
语句和指定 CommandNotFoundException 类型的特定trap
语句。
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 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.
由于 PowerShell 无法将“nonsenseString”识别为 cmdlet 或其他项,因此它将返回 CommandNotFoundException 错误。 此终止错误由特定 trap
语句捕获。
以下脚本示例包含具有不同错误的相同 trap
语句:
trap {"Other terminating error trapped" }
trap [System.Management.Automation.CommandNotFoundException]
{"Command error trapped"}
1/$null
运行此脚本会生成以下结果:
Other terminating error trapped
RuntimeException:
Line |
4 | 1/$null
| ~~~~~~~
| Attempted to divide by zero.
尝试除以零不会创建 CommandNotFoundException 错误。 相反,该错误由另一 trap
个 语句捕获,这会捕获任何终止错误。
捕获脚本块中的错误
默认情况下,当引发终止错误时,执行将传输到 trap 语句。 运行 trap
块后,控制将返回到错误位置之后的下一个语句块。
例如,当语句中 foreach
发生终止错误时, trap
语句将运行,并在 块之后 foreach
的下一个语句(而不是块中 foreach
)继续执行。
trap { 'An error occurred!'}
foreach ($x in 3..0) {
1/$x
'after division'
}
'after loop'
0.333333333333333
after division
0.5
after division
1
after division
An error occurred!
RuntimeException: untitled:Untitled-1:3:4
Line |
3 | 1/$x
| ~~~~
| Attempted to divide by zero.
after loop
在上面的输出中,可以看到循环一直持续到最后一次迭代。
当脚本尝试将 1 除以 0 时,将引发终止错误。 将跳过脚本块的 foreach
其余部分, try
运行 语句,脚本在 scriptblock 之后 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 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.
function1 was completed
trap
函数中的 语句捕获错误。 显示消息后,PowerShell 继续运行函数。 请注意, Function1
已完成。
将此与以下示例进行比较,该示例具有相同的错误和 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 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.
在此示例中,“function2 已完成”命令未运行。 在这两个示例中,终止错误都发生在 函数中。 但是,在此示例中, trap
语句位于 函数外部。 运行 语句后 trap
,PowerShell 不会返回到 函数中。
注意
为同一错误条件定义多个陷阱时,将使用第一个 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
来确定脚本或命令在终止错误后是否继续运行。
如果在语句trap
列表中包括break
语句,PowerShell 将停止该函数或脚本。 以下示例函数在 break
语句中使用 trap
关键字 (keyword) :
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
关键字 (keyword) ,因此函数不会继续运行,并且“函数已完成”行未运行。
如果在 continue
语句中包含trap
关键字 (keyword) ,PowerShell 会在导致错误的语句之后恢复,就像不使用 break
或 continue
一样。 但是,continue
使用 关键字 (keyword) 时,PowerShell 不会将错误写入错误流。
以下示例函数在 continue
语句中使用 trap
关键字 (keyword) :
function continue_example {
trap {
"Error trapped"
continue
}
1/$null
"Function completed."
}
continue_example
Error trapped
Function completed.
捕获错误后,函数会恢复,并运行“Function completed”语句。 不会将错误写入错误流。
备注
trap
语句提供了一种简单方法来广泛确保处理范围内的所有终止错误。 若要进行更精细的错误处理,请使用 try
/catch
使用 catch
语句定义陷阱的块。 语句 catch
仅适用于关联 try
语句中的代码。 有关详细信息,请参阅 about_Try_Catch_Finally。