如何在抛出异常时终止PowerShell脚本?异常处理疑问
问题详情
原始脚本如下:
If ($True) { Throw [FooException]::New("some foo") } If ($True) { Throw [BarException]::New("some bar") }
正常情况下,抛出FooException后脚本会直接终止,但如果创建FooException实例时出了错,会同时抛出这个创建失败的异常和后面的BarException,你想知道为什么会这样,还想找一种不用重抛异常就能终止脚本的方法,觉得在throw后面加Exit 1的方式不太妥当。
你之前试过两种方法,都没达到预期:
- 设置
$ErrorActionPreference = 'Stop':错误直接输出到主机,没进入错误流; - 把代码放进
try-catch块然后重抛:
Try { If ($True) { Throw [FooException]::New("some foo") } If ($True) { Throw [BarException]::New("some bar") } } Catch { Throw $_ }
原因解析
- 创建自定义异常实例时的错误属于非终止错误(PowerShell默认行为),这种错误不会中断后续代码执行,所以第二个
If块的BarException会接着抛出; $ErrorActionPreference = 'Stop'不管用是因为,创建异常实例是调用.NET方法的操作,这类错误不受PowerShell全局错误偏好设置管控,这个设置只对PowerShell自身的命令/cmdlet生效。
无需重抛的终止方案
方案1:强制将创建异常的错误转为终止错误
临时修改错误偏好设置,确保创建异常时的错误能终止脚本,执行完再恢复原设置:
$originalErrorAction = $ErrorActionPreference $ErrorActionPreference = 'Stop' Try { If ($True) { Throw [FooException]::New("some foo") } If ($True) { Throw [BarException]::New("some bar") } } Finally { $ErrorActionPreference = $originalErrorAction }
这样只要创建FooException时出错,脚本会立刻终止,不会走到BarException的代码。
方案2:用trap全局捕获并终止
trap可以在脚本范围内自动捕获未处理的异常,直接终止脚本,不用显式重抛:
trap { exit 1 # 直接终止整个脚本进程 # 如果不想关闭控制台,用return也能终止当前脚本:return } If ($True) { Throw [FooException]::New("some foo") } If ($True) { Throw [BarException]::New("some bar") }
不管是创建异常时的错误还是抛出的自定义异常,trap都会捕获,执行exit 1直接终止,不会继续执行后续代码。
方案3:提前检查异常实例是否创建成功
先创建异常对象,确认没问题再抛出,创建失败直接终止:
If ($True) { $fooEx = [FooException]::New("some foo") if (-not $fooEx) { exit 1 } Throw $fooEx } If ($True) { Throw [BarException]::New("some bar") }
这种方式更直接,提前拦截创建失败的情况,避免后续代码执行。
内容的提问来源于stack exchange,提问作者GrandeKnight
相关产品推荐
相关产品推荐

