PowerShell调用REST API出错时如何抛出错误并终止脚本执行
核心问题原因
你的脚本出错后不终止、catch不生效是几个明确问题导致的:
- 非终止错误无法触发catch:PowerShell的
Invoke-WebRequest、Invoke-RestMethod默认抛出的是非终止错误,这类错误不会进入try/catch流程,只有加-ErrorAction Stop参数将错误转为终止错误才会被捕获。你当前代码里只有第二次调用Invoke-RestMethod加了这个参数,第一次获取令牌的Invoke-WebRequest完全没加,这一步出错时catch根本不会触发,脚本会直接往后跑。 - Catch块吞了错误:现在的catch块只做了信息打印,没有主动抛出终止错误,打印完成后脚本会自然继续执行后续逻辑,不会停在故障点。
- 变量低级覆盖bug:你先拼接了微软令牌端点的地址赋值给
$uri,紧接着又把业务接口地址赋值给同名$Uri(PowerShell变量不区分大小写),导致获取令牌的POST请求实际发往了业务接口,逻辑本身就有错误。 - 全局错误策略默认是继续执行:PowerShell默认全局
$ErrorActionPreference值为Continue,所有没显式指定错误处理参数的命令出错后都会继续运行。
修复后代码
# 全局设置:遇到任何错误立即终止,避免非预期的继续执行 $ErrorActionPreference = 'Stop' try { $clientSecret = '' $clientId = '' $tenantId = '' # 分开定义两个接口地址,避免变量覆盖 $tokenUri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" $dataUri = 'https://apiserver.com/v1/data' $networkSavePath = '\\你的网络共享路径\api响应.json' # 构造令牌请求body $tokenBody = @{ client_id = $clientId client_secret = $clientSecret scope = 'https://graph.microsoft.com/.default' grant_type = 'client_credentials' } # 获取令牌,显式指定ErrorAction Stop确保错误可捕获 $tokenRequest = Invoke-WebRequest -Method Post -Uri $tokenUri -ContentType 'application/x-www-form-urlencoded' -Body $tokenBody -UseBasicParsing -ErrorAction Stop $token = ($tokenRequest.Content | ConvertFrom-Json).access_token # 调用业务接口,同样加ErrorAction Stop $apiResponse = Invoke-RestMethod -Method Get -Uri $dataUri -ContentType 'application/json' -Headers @{Authorization = "Bearer $token"} -ErrorAction Stop # 所有接口调用成功后,再把响应存到网络共享 $apiResponse | ConvertTo-Json -Depth 10 | Out-File -FilePath $networkSavePath -Encoding utf8 -ErrorAction Stop } catch { # 打印自定义错误信息 Write-Host "=== 接口调用出错 ===" Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__ Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription Write-Host "ErrorMessage:" $_.ErrorDetails.Message # 重新抛出PowerShell原生错误,强制脚本在当前位置终止,不执行后续逻辑 throw $_ } # 后续其他业务逻辑只有前面全成功才会走到这
关键说明
- 全局
$ErrorActionPreference = 'Stop'是第一道保险,覆盖所有未单独指定错误处理参数的命令,确保任何错误都会触发脚本终止。 - 两个REST调用和文件写入操作都单独加
-ErrorAction Stop是第二道保险,避免全局配置被意外修改时错误逃逸。 - 接口地址用不同变量名存储,从根源上避免变量覆盖导致的请求地址错误。
- 写入网络共享的逻辑放在所有接口调用成功之后,只有拿到合法响应才执行写入,避免存无效错误数据。
- Catch块最后用
throw $_抛出捕获到的原始错误对象,既保留了PowerShell原生的错误栈信息,也能保证脚本执行完错误打印后立即终止,不会继续跑后面的逻辑。
内容的提问来源于stack exchange,提问作者ITHelpGuy
相关产品推荐
相关产品推荐

