about_Trap

简短说明

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

详细说明

终止错误阻止语句运行。 如果 PowerShell 未以某种方式处理终止错误,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 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 中,这称为 hoisting。 这意味着 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 类型。 此语句捕获由未知命令创建的错误。 它还检测其他错误类型。

可以在脚本中有多个 trap 语句。 每种错误类型只能由一个 trap 语句捕获。 发生终止错误时,PowerShell 会从当前执行范围开始搜索具有最具体匹配项的 。trap

以下脚本示例包含错误。 该脚本包括一个用于捕获任何终止错误的常规 trap 语句,以及一个指定 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 错误。 此终止错误由 specific 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 错误。 相反,该错误由 other 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 时,将引发终止错误。 跳过 scriptblock 的其余部分 foreachtry 运行语句,并且脚本在 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 已完成。

将此与以下示例进行比较,该示例具有相同的 error 和 trap statement。 在此示例中,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 was completed” 命令。 在这两个示例中,终止错误发生在函数中。 但是,在此示例中,trap 语句不在函数之外。 PowerShell 在语句运行后 trap 不会返回到函数中。

谨慎

当为同一错误条件定义多个陷阱时,将使用第一个词法定义的陷阱 trap (范围内的最高)。

在以下示例中,仅 trap 运行 with “whoops 1” 的 。

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

重要

Trap 语句的范围限定为它的编译位置。 如果函数或点源脚本中有 trap 语句,则当函数或点源脚本退出时,将删除内部的所有 trap 语句。

使用 break 和 continue 关键字

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

如果在 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 会在导致错误的语句后恢复,就像没有 breakcontinue一样。 但是, continue 使用关键字时,PowerShell 不会将错误写入错误流。

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

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

另请参阅