about_Trap

简短说明

描述处理终止错误的关键字。

长说明

终止错误阻止语句运行。 如果 PowerShell 不以某种方式处理终止错误,PowerShell 也会停止在当前管道中运行函数或脚本。 在其他语言(如 C#)中,终止错误称为异常。

关键字 trap 指定要在发生终止错误时运行的语句列表。 trap 语句可以通过以下方式处理终止错误:

  • 在处理 trap 语句块并继续执行包含该 trap语句的脚本或函数后显示错误。 此选项为默认行为。

    备注

    当从属脚本块(如 if 语句或 foreach 循环)中发生终止错误时,该块中的 trap 语句在从属脚本块之外的下一个语句继续执行。

  • 显示包含语句中的 using breaktrap脚本或函数trap的错误和中止执行。

  • 使错误保持沉默,但继续执行包含trapcontinue语句中的trap脚本或函数。

语句列表 trap 可以包含多个条件或函数调用。 A trap 可以编写日志、测试条件,甚至运行另一个程序。

语法

trap 语句具有以下语法:

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

trap 语句包含在发生终止错误时要运行的语句列表。 语句 traptrap 关键字组成,可选后跟类型表达式,以及包含捕获错误时要运行的语句列表的语句块。 类型表达式优化捕获的错误 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 语句。 可以定义 A 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 运行语句,脚本在脚本块之后 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 语句。

使用中断和继续关键字

可以使用语句中的breaktrapcontinue关键字来确定脚本或命令在终止错误后是否继续运行。

如果在语句列表中包括语句breaktrap,PowerShell 将停止函数或脚本。 以下示例函数在语句中使用breaktrap关键字:

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关键字,因此该函数不会继续运行,并且“函数已完成”行未运行。

如果在continue语句中包含关键字,则 PowerShell 将在导致错误的语句之后恢复,就像在语句中trap没有或continue那样breakcontinue但是,借助关键字,PowerShell 不会将错误写入错误流。

以下示例函数在 continue 语句中使用 trap 关键字:

function continue_example {
    trap {
        "Error trapped"
        continue
    }
    1/$null
    "Function completed."
}

continue_example
Error trapped
Function completed.

该函数在捕获错误后恢复,“函数已完成”语句运行。 不会将错误写入错误流。

备注

trap 语句提供了一种方法来确保处理脚本块中的所有终止错误。 有关更精细的错误处理,请使用 try/catch 使用 catch 语句定义陷阱的块。 这些 catch 语句仅适用于关联 try 语句中的代码。 有关详细信息,请参阅 about_Try_Catch_Finally

另请参阅