More On ASP.NET’s Broken Error Handling

I’ve looked a bit more into the way ASP.NET handles HTTP errors, and frankly it now seems not just irritating, but downright bizarre.

By the way, although the original post was about a 5xx series server error, this also applies to 4xx series client errors. We’ll take the familiar 404 Not Found as an example case.

Here are the main parts (with some headers and the body omitted) of the response to a broken request for Raymond Chen’s blog – I deliberately misspelled “default” as “defult” to trigger a 404:

HTTP/1.1 302 Found
Date: Wed, 10 Dec 2008 17:46:51 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
CommunityServer: 2.1.61025.2
Location: /error-notfound.aspx?aspxerrorpath=/oldnewthing/defult.aspx
Content-Type: text/html; charset=utf-8
Content-Length: 176

So, a request for something that is not found returns 302 Found. Nice.

What happens when the browser follows the redirection to /error-notfound.aspx?aspxerrorpath=/oldnewthing/defult.aspx? This happens:

HTTP/1.1 404 Not Found
Date: Wed, 10 Dec 2008 17:46:52 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
CommunityServer: 2.1.61025.2
Content-Type: text/html; charset=utf-8
Content-Length: 11769

So, just to get this straight: when something is not found, ASP.NET returns a 302 Found response redirecting the client elsewhere. Then, when the redirect is followed, it returns a 404 Not Found response, despite the fact that this page clearly has been found, and it was the page that redirected us here that was not found.

Weird. Just plain weird.

Update: an online acquaintance (I don’t have a URL for him) has pointed me to a page on MSDN where the rationale for this behaviour is presented:

Redirect creates a new Context, Transfer does not. Redirect requires a round-trip to the browser, Transfer does not. As a result of this round-trip, Redirect rewrites the URL to reflect the location of the error page, Transfer does not.

If this seems to be an argument in favor of Transfer, it isn’t. The rationale of the ASP.NET development team is that Redirect accurately displays the URL of the custom error page

However, at no point is it explained why displaying such an implementation detail to clients is preferable. Given that the article starts with the words:

The quality of a site should be measured not only by how well it works, but by how gracefully it fails.

it seems strange that it then recommends a technique which causes sites to fail in a singularly graceless manner.

My suggestion would be to modify your ASP.NET application configurations so that the customError capability uses the Transfer technique instead of Redirect. If that

…breaks a tenet of the design philosophy of ASP.NET…

then so be it.