I don't really like how HttpWebRequest does this, in a lot of cases a non-200 status code isn't really an "error" so making you go through exception handling is a bother. Nonetheless, you have the tools you need.

If you check the documentation for HttpWebRequest.GetResponse(), you'll find a list of exceptions it might throw. Handling all of them is important, but in this case you are writing code that needs to do something special for WebException, which is thrown when "an error occurred while processing the request".

If that exception is thrown, then the HttpWebResponse was not actually created for the Using statement! You could have rearranged things to get access to that variable, but you would have found it was Nothing. Generally, methods in .NET either do what they say OR throw an exception. Anyway, peek at the WebException documentation. Read all of its properties. The most important one is Response, which gives you access to the WebResponse that WOULD HAVE been created. This is almost the same thing as an HttpWebResponse, and is probably safe to cast, but I don't know yet if you need to.

So:
Code:
Try
    Using response As HttpWebResponse = ...
        ...
    End Using
Catch ex As WebException
    Dim response As HttpWebException = CType(ex.Response, HttpWebException)
    Dim statusCode As HttpStatusCode = e.StatusCode
    If statusCode = HttpStatusCode.Unauthorized Then
        ...
    End If
End Catch
A good question: Why didn't I put a Using statement in the Catch block? I have a hunch you aren't supposed to. This HttpWebResponse belongs to the WebException. It's that type's responsibility to dispose of it. If I dispose of it, I might cause trouble. The examples on MSDN don't dispose of the response when they get it. THAT SAID, it might be an oversight, and they might not have thought about it. So if you're having problems, add a Using statement to make sure it gets disposed.