Search code examples
powershellexceptionhttp-status-code-404http-status-code-429invoke-webrequest

How to differentiate Invoke-WebRequest exception (HTTP error code) in try catch statement


I've created a script to download specific files on the Internet with a PowerShell script using the Invoke-WebRequest cmdlet.

I've 2 known exception I would like to handle: 404 and 429.

I'm currently working with a try/catch statement:

try {
    Invoke-WebRequest -Uri $download_url -OutFile $srr_file
} catch {
    ...snip...
}

But for both errors, I've the same code and it's not what I would like to do:

try {
    Invoke-WebRequest -Uri $download_url -OutFile $srr_file
} catch [something here] {
    # Here the code I would like to write if the HTTP response is 404 File not found
    # Will certainly be a continue command
} catch [something here] {
    # Here the code I would like to write if the HTTP response is 429 Too many request
    # Will certainly be a sleep command for 1 hour
}

Here the output of the command in both situation:

Error HTTP 404
Invoke-WebRequest : The remote server returned an error : (404) Not Found.
At line:1 char:1
+ Invoke-WebRequest -Uri https://<censored> -Outfile test.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

Error HTTP 429
Invoke-WebRequest : The remote server returned an error : (429) Too Many Requests.
At line:1 char:1
+ Invoke-WebRequest -Uri "https://<censored> -Outfile test.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

Solution

  • You can do something like this:

    try 
    {
        $response = Invoke-WebRequest -Uri $download_url -OutFile $srr_file
    } 
    catch 
    {
        switch ($_.Exception.Response.StatusCode.Value__)
        {
            404 { 
                // Here´s the code I would like to write if the HTTP response is 404 File not found
                // Will certainly be a continue command            
                }
            429 {
                // Here´s the code I would like to write if the HTTP response is 429 Too many request
                // Will certainly be a sleep command for 1 hour 
                }
        }
    }
    

    Since it's the same exception being thrown, you wont be able to catch them separately.