This HttpHandler does not send a response if con.Open() throws an exception, for example if faultyConnectionString has an invalid database name. Why?
public void ProcessRequest(HttpContext context)
{
int status = 400;
string message = "Test error!";
string faultyConnectionString = "Data Source=LOCALHOST\\SQLEXPRESS;Initial Catalog=XXX;User ID=XXX;Password=XXX";
try
{
using (SqlConnection con = new SqlConnection(faultyConnectionString))
{
//throw new Exception("This works as expected, and is returned to client");
con.Open();
}
}
catch (Exception ex)
{
status = 500;
message = "Test Exception: " + ex.Message;
}
context.Response.StatusCode = status;
context.Response.StatusDescription = message;
}
Here is how I am handling the call in the client:
function GetContacts() {
$.ajax({
type: "POST",
url: "xxx.ashx",
data: "",
contentType: "application/x-www-form-urlencoded; charset=utf-8",
dataType: "text", // "json",
success: function (response, a, b) {
alert(response.status + " " + response.statusText);
},
error: function (response, a, b) {
alert(response.status + " " + response.statusText);
}
});
}
If I F12 in FireFox it shows me that there is no Response received after the request is sent. In IE it shows me "SCRIPT7002: XMLHttpRequest: Network Error 0x2ef3, Could not complete the operation due to error 00002ef3.". In both cases the jquery ajax call returns status=0 and statusText="error".
If I comment out the two lines inside the catch block then it works as expected, sending the 403 code to the client and ignoring the exception.
Different types of exceptions do not have the same problem. If I throw a new Exception() before con.Open() then it also works as expected. What is different with SqlException?
UPDATE: The very first time I hit ProcessRequest it gets called 5 times in succession before the client shows the status=0 result (breakpoint on first line is hit 5 times).
FIDDLER: If I fire up Fiddler it (fiddler) intercepts the transaction and sends "504 Fiddler - Receive Failure" to my ajax call. Looks like the initial repetition may be a retry mechanism, when fiddler is active it does it 13 times. Fiddler reports: "Session #xxx raised exception System.Net.Sockets.SocketException An existing connection was forcibly closed by the remote host".
I believe the way your client (browser) handles 404 errors is what is causing this, and each browser type is handling the error differently. 404 errors are specific to "Not Found" so you may want to use a different error code such as a 500 error. More info on error codes is available here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
Please keep in mind that passing back detailed error messages to a client could be a security issue due to information leakage. You may be better off passing back a generic error to the client and logging detailed error information on the server side.
Edit:
Testing this locally, the way you are setting context.Response.StatusDescription
to contain ex.Message
is producing an invalid HTTP response. Try only placing text such as Internal Server Error in there. Additional details can be added to the body of the response using context.Response.Write(bodyText)
but please keep the security implications of this in mind.