Friday, August 13, 2010

System.Web.HttpException: The remote host closed the connection. The error code is 0x80072746


DARE TO SHARE?
Today we got an error mail from one of our production sites, where we had configured to send the exception details to an email address so that we can troubleshoot. Following was the error message:

System.Web.HttpException: The remote host closed the connection. The error code is 0x80072746

I was assigned to troubleshoot this issue and found that, this exception generally happens when you have download functionality in your Asp.net applications and when user starts the download process, but, the download process does not complete for one of the following reasons:
  • User cancels the download
  • User navigates to another page
  • User closes the page
  • The connection closes
We have a file download page that allows the user to download files. This page internally hits another page that actually writes the file content to the browser. From the exception detailed message, I got to know that, the exception was taking place while executing the following URL:

/Pages/DocumentDownload.aspx?documentID=101

Detailed reason:

By default, Response.BufferOutput property is set to "true" and hence the Asp.net process writes data/output to the buffer, instead of the output stream. When the page is finished processing, the buffered output is flushed to the output stream and hence, sent to the browser. This is usually done to avoid multiple data transfer process over the network and hence optimize performance by sending the overall page output in a single Response.

But, when a page writes a file content (Or, a file) in the Response, usually, we used to flush the buffer immediately after we write the file content in the output stream, so that, the file content is sent to browser immediately, instead of waiting for the page to complete its' execution process process. In general, following is the code that we usually use.

Response.WriteFile("A File"); //Or, //Response.BinaryWrite(FileContent)
Response.Flush();
Response.End();

Now, imagine the following scenario:
  • User started to download the file from the download prompt (As a result of the Response.WriteFile()), data is stored in buffer and the buffer is overflown and a stream of binary data started to flow from server to client.
  • For some reason, the download process is cancelled (For one of the above mentioned reasons)
  • Meanwhile, the Asp.net process tries to Flush() the buffer content to the output stream, that is already closed by the client.
  • Exception occurs.
Probable solution:

Despite the fact that, this exception is not a very important one and can be ignored, but, we can have a try to solve this issue.Trying to avoid the Response.Flush() may result in not occurring the exception and the File download codes could be written as follows:


Response.Buffer = false;
//Disabling buffering so that, the file content is immediately written to output stream

Response.Clear();
Response.ContentType = projectDocument.MimeType;
Response.AppendHeader("content-disposition", "attachment; filename=" + HttpUtility.UrlEncode(projectDocument.FileName));
Response.BinaryWrite(projectDocument.FileContent);

//Response.Flush();
//Response.End();
//No need to Flush() and End() the response as the output stream is not buffered
I didn't test it yet in the production server, but, hopefully this would stop the exception from being generated.

4 comments:

Anonymous said...

very well explained.. with detail! i like.

Anonymous said...

Have you tested this yet? Does it work?

Shubho said...

No, I didn't test this solution yet. But, I'll try to test it soon and put my feedback here.

Besides, I believe, the best possible approach to deal with this exception is just to avoid this exception. So, if there is any global exception handler defined somewhere (Say, in the Global.asax) in our application, we could check the Exception type (and, probably the exception message) and do not log or handle it if the exception is of such type.

Varun N. Shringarpure said...

Nice article. Thanks for this. Very well explained...

Post a Comment