Mads Moi-Aune
Get status code for failed webrequests in Powershell
If you are sending web requests with Powershell you will notice that if your requests fails, that is if it returns any status code other than 2xx, it will thrown an error. Now, how do get the details of the failed request?
StatusCode
In Powershell, when you use Invoke-WebRequest
or Invoke-RestMethod
, it will give you details about the failed request in the $_.Exception.Response
object. Let’s say you want to know if the error is because of a bad request or an internal server error, you can do this:
try {
$response = Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/users/11"
} catch {
$StatusCode = $_.Exception.Response.StatusCode
if ($StatusCode -eq [System.Net.HttpStatusCode]::NotFound) {
Write-Error "User was not found!"
} elseif ($StatusCode -eq [System.Net.HttpStatusCode]::InternalServerError) {
Write-Error "InternalServerError: Something went wrong on the backend!"
} else {
Write-Error "Expected 200, got $([int]$StatusCode)"
}
}
If you want to compare the status code as an integer you can just cast the status code, which is as you can see from the example above, a System.Net.HttpStatusCode enum.
try {
$response = Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/users/11"
} catch {
$StatusCode = [int]$_.Exception.Response.StatusCode
if ($StatusCode -eq 404) {
Write-Error "User was not found!"
} elseif ($StatusCode -eq 500) {
Write-Error "InternalServerError: Something went wrong on the backend!"
} else {
Write-Error "Expected 200, got $([int]$StatusCode)"
}
}
As always when using namespaces in Powershell you can define them at top and it will save you some typing.
using namespace System.Net
try {
$response = Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/users/11"
} catch {
$StatusCode = $_.Exception.Response.StatusCode
if ($StatusCode -eq [HttpStatusCode]::NotFound) {
Write-Error "User was not found!"
} elseif ($StatusCode -eq [HttpStatusCode]::InternalServerError) {
Write-Error "InternalServerError: Something went wrong on the backend!"
} else {
Write-Error "Expected 200, got $([int]$StatusCode)"
}
}
Response content
Many API’s will give you additional information in the response body when a request fails. This content is not stored i the $_.Exception.Response
object, but in $_.ErrorDetails.Message
. To simply our previous example we can do this.
NOTE: https://jsonplaceholder.typicode.com
does not return status code or an additional response body when failing, but in theory if your API supports it, this is how you would extract that information.
using namespace System.Net
try {
$response = Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/users/0"
} catch {
$StatusCode = $_.Exception.Response.StatusCode
$ErrorMessage = $_.ErrorDetails.Message
Write-Error "$([int]$StatusCode) $($StatusCode) - $($ErrorMessage)"
}