FSharp.Data
FSharp.Data copied to clipboard
How to extract the status code from a WebException generated by XmlProvider<...>.Load ?
Hi,
I'm using XmlProvider to fetch and parse RSS feeds. I want to handle HTTP Errors but I cannot find a way to get the status code of a webexception.Response.
The C# approach is to cast the WebResponse to HttpWebResponse, that doesn't seem to work with the response from MyXml.Load.
To be more explicit, look at the code below. downcastWebResponse tries to downcast the WebResponse from the exception into an HttpWebResponse. Unfortunately it fails thus returns None.
Without the guard, if I do something like let resp = e.Response :?> HttpWebResponse I get the error Unhandled Exception: System.InvalidCastException: Specified cast is not valid..
So, my question is: How can I get the status code from the exception response?
And if I have to cast to HttpWebResponse, how can I do it?
open System
open System.Net
open FSharp.Data
type Rss = XmlProvider<sampleRssFile>
let feedWith404 = "http://feeds.reuters.com/reuters/blogs/the-human-impact"
let downcastWebResponse (wr: WebResponse) =
match wr with
| :? HttpWebResponse as hwr -> Some(hwr.StatusCode)
| _ -> None
let loadRssIndex (url: string) : Choice<Rss.Rss, RssException> =
try
Choice1Of2 (Rss.Load(url))
with
| :? WebException as e ->
match e.Status with
| WebExceptionStatus.ProtocolError ->
let statusCode = downcastWebResponse e.Response // <== try to downcast
match statusCode with
| Some status ->
match status with
| HttpStatusCode.NotFound ->
Choice2Of2 (RssException.IndexNotFound e)
| _ -> reraise()
| None -> reraise() // <== downcast failed
| _ -> reraise()
// Run
loadRssIndex feedWith404
The HttpWebResponse is sitting on e.Response.res, a private member of Response on WebException. It's not only private, it's protected or internal, so we can't expose it in a subclass. Would love to have access to it, as mapping a WebResponse to an HttpWebResponseusing the public members is error-prone at best.
This issue should remain open. So far as I can tell, there is still no convenient way to retrieve the HTTP status code of a WebException. The least-worst way is to extract it from e.Message, which is a string.
This is a major pitfall. If you Google for C# solutions, they'll tell you to downcast to HttpWebResponse, which does not work for FSharp.Data's WebResponse.
Not sure why it was closed, I don’t remember closing it? Pretty I didn’t interact with this issue since I opened it in 2016. Anyway, it’s reopened.