Get HTTP request and tolerate 500 server error in powershell
Asked Answered
D

1

16

In Powershell v3.0 I would like to return the response code from an HTTP GET, such as 200 OK or 500 Internal Server Error. (This is for a hack-deploy to do a quick warmup of a deployed site and see if it works, a sort of a mini acceptance test. The status code is truly all I want.)

Against my wishes, HttpWebRequest.GetResponse throws an error when it receives a 500 Internal Server Error. This is annoying because it isn't really an error to me in my use case. Anyway, I figured I could catch the exception and still peel out the underlying response code, but I'm having trouble with that.

Here's some almost-working code:

function WebResponseStatusCode (
   [Parameter(Mandatory=$true)][string] $url
) {
    $req = [system.Net.HttpWebRequest]::Create($url)
    try {
        $res = $req.GetResponse();
        $statuscode = $res.statuscode;
    }
    catch [System.Net.WebException] {
        #the outer error is a System.Management.Automation.ErrorRecord
        Write-Host "error!"
        return = $_.Response.statuscode; #nope
    }
    finally {
        if (!($res -eq $null)) {
           $res.Close();
        }
    }
   return $statuscode;
}

The problem is of course that $_ has no Response property. Neither does $_.InnerException, even when cast:

return [System.Net.WebException]($_.InnerException)

I've played around with $_ | Get-Member and exploring all its properties. I thought $_.TargetObject had some promise but it doesn't appear to.

(Update) I also think I tried variations on $_.Exception.Response though may have gotten it wrong.

Getting just a response code seems like such a simple thing to do.

Dedicate answered 27/3, 2014 at 19:9 Comment(3)
I've seen other folks run into this issue. It should probably be logged as an enhancement request on connect.microsoft.com to not throw on 5xx status codes.Increscent
Do you see the same results with Invoke-WebRequest? I don't have a server that's delivering a 500 result to test against.Ragg
The strange thing is that Invoke-WebRequest handles these errors differently from for example Test-Connection (i.e. ping). Test-Connection uses -ErrorVariable and -ErrorAction as you would expect. Invoke-WebRequest just calls Write-Error when something goes wrong.Caryophyllaceous
I
20

Here's an example, though it does a couple more things to allow you to test redirections as well as expected exceptions.

function GetWebSiteStatusCode {
    param (
        [string] $testUri,
        $maximumRedirection = 5
    )
    $request = $null
    try {
        $request = Invoke-WebRequest -Uri $testUri -MaximumRedirection $maximumRedirection -ErrorAction SilentlyContinue
    } 
    catch [System.Net.WebException] {
        $request = $_.Exception.Response

    }
    catch {
        Write-Error $_.Exception
        return $null
    }
    $request.StatusCode
}

GetWebSiteStatusCode -testUri "https://www.google.com/"
GetWebSiteStatusCode -testUri "https://www.google.com/foobar"
GetWebSiteStatusCode -testUri "http://google.com/" -maximumRedirection 0
GetWebSiteStatusCode -testUri "https://accounts.google.com" -maximumRedirection 0
GetWebSiteStatusCode -testUri "https://www.googleapis.com/coordinate/v1/teams/1/custom_fields?fields=1111&key="
GetWebSiteStatusCode -testUri "https://www.googleapis.com/shopping/search/v1/test/products/sasdf/asdf/asdf?key="

#Next test would be for an expected 500 page.
#GetWebSiteStatusCode -testUri "https://www.somesite.com/someurlthatreturns500"
Irascible answered 27/3, 2014 at 22:31 Comment(4)
This is great. I knew there had to be a way to do it more easily. It's too bad that you still have to catch an exception, but at least it's working! I don't know why my tries at using $_.Exception.Response didn't work.Dedicate
Note that the exception returns a System.Net.HttpWebResponse, not a Microsoft.PowerShell.Commands.HtmlWebResponseObject, and in my tests, the response stream seems to have already been read.Anatol
I have tried this and it seems to work for most error codes. However, when I should be receiving a 12029 (system cannot locate the resource specified) code, this gives me a 0... please adviseSuckow
Nice... The trick is to cast the caught exception to a WebExceptionMacrocosm

© 2022 - 2024 — McMap. All rights reserved.