如何在PowerShell的try/catch中区分Invoke-WebRequest的404与429异常
区分处理Invoke-WebRequest的404和429错误
没问题,咱们可以通过在catch块里解析异常的响应状态码,精准区分这两种HTTP错误,实现各自的处理逻辑。下面分两种PowerShell版本给出解决方案:
Windows PowerShell 5.x及以下版本
这个版本里,Invoke-WebRequest抛出的是System.Net.WebException,我们可以直接从异常对象中提取响应状态码:
try { Invoke-WebRequest -Uri $download_url -OutFile $srr_file } catch [System.Net.WebException] { # 获取服务器返回的响应对象 $response = $_.Exception.Response if ($response -ne $null) { # 将状态码转换为枚举类型,方便识别 $statusCode = [System.Net.HttpStatusCode]$response.StatusCode switch ($statusCode) { # 处理404文件未找到 'NotFound' { Write-Host "⚠️ 目标文件未找到(HTTP 404),跳过当前任务" continue } # 处理429请求过多 'TooManyRequests' { Write-Host "⚠️ 请求过于频繁(HTTP 429),将休眠1小时后重试" Start-Sleep -Seconds 3600 # 可选:如果需要自动重试,取消下面的注释 # Invoke-WebRequest -Uri $download_url -OutFile $srr_file } # 处理其他未定义的HTTP错误 default { Write-Host "❌ 遇到未处理的HTTP错误:$statusCode" # 重新抛出异常,避免吞掉未知错误 throw $_ } } } else { # 处理无响应的异常(比如网络断开、DNS解析失败) Write-Host "❌ 网络连接异常:$($_.Exception.Message)" throw $_ } }
PowerShell 7+版本
PowerShell 7及以上改用HttpClient底层实现,抛出的异常类型变为System.Net.Http.HttpRequestException,需要从内部嵌套的异常中提取响应信息:
try { Invoke-WebRequest -Uri $download_url -OutFile $srr_file } catch [System.Net.Http.HttpRequestException] { # 从内部异常中获取WebException对象 if ($_.Exception.InnerException -is [System.Net.WebException]) { $response = $_.Exception.InnerException.Response $statusCode = [System.Net.HttpStatusCode]$response.StatusCode switch ($statusCode) { 'NotFound' { Write-Host "⚠️ 目标文件未找到(HTTP 404),跳过当前任务" continue } 'TooManyRequests' { Write-Host "⚠️ 请求过于频繁(HTTP 429),将休眠1小时后重试" Start-Sleep -Seconds 3600 # 可选:自动重试请求 # Invoke-WebRequest -Uri $download_url -OutFile $srr_file } default { Write-Host "❌ 遇到未处理的HTTP错误:$statusCode" throw $_ } } } else { Write-Host "❌ 请求异常:$($_.Exception.Message)" throw $_ } }
关键说明
- 我们通过
[System.Net.HttpStatusCode]枚举将数字状态码转换为可读性更强的名称(比如NotFound对应404),也可以直接用数字判断(比如404代替'NotFound')。 - 添加了非HTTP异常的处理分支,避免网络连接类错误被误判。
- 429场景下的休眠逻辑可以根据实际需求调整时长,也可以添加重试次数限制。
内容的提问来源于stack exchange,提问作者locobastos




