41

How do I handle a server error in the middle of an Http message?

Assuming I already sent the header of the message and I am streaming the the body of the message, what do I do when I encounter an unexpected error.

I am also assuming this error was caused while generating the content and not a connection error.

(Greatly) Simplified Code:

// I can define any transfer encoding or header fields i need to.
send(header);  // Sends the header to the Http client.

// Using an iterable instead of stream for code simplicity's sake.
Iterable<String> stream = getBodyStream();
Iterator<String> iterator = stream.iterator();

while (iterator.hasNext()) {
    String string;
    try {
       string = iterator.next();   
    catch (Throwable error) { // Oops! an error generating the content.
        // What do i do here? (In regards to the Http protocol)
    }

    send(string);
}

Is there a way to tell the client the server failed and should either retry or abandon the connection or am I sool?

The code is greatly simplified but I am only asking in regards to the protocol and not the exact code.

Thank You

user1964161
  • 565
  • 4
  • 6

2 Answers2

26

One of the following should do it:

  1. Close the connection (reset or normal close)
  2. Write a malformed chunk (and close the connection) which will trigger client error
  3. Add a http trailer telling your client that something went wrong.
  4. Change your higher level protocol. Last piece of data you send is a hash or a length and the client knows to deal with it.
  5. If you can generate a hash or a length (in a custom header if using http chunks) of your content before you start sending you can send it in a header so your client knows what to expect.

It depends on what you want your client to do with the data (keep it or throw it away). You may not be able to make changes on the client side so the last option will not work for example.

Here is some explanation about the different ways to close. TCP option SO_LINGER (zero) - when it's required.

Community
  • 1
  • 1
jdb
  • 4,419
  • 21
  • 21
  • trailing header seems less safe because it's possible that some of the body was written to the response, so then adding a trailing header wouldn't be recognized AFAICT. – Alexander Mills May 11 '18 at 19:41
  • 1
    @AlexanderMills trailer header informs client to expect some header in the trailer portion of Chunked Transfer. So you send: Headers, part1, part2, .., partN, trailer – Kangur Nov 05 '21 at 15:08
-10

I think the server should return a response code start with 5xx as per RFC 2616.

Server Error 5xx

Response status codes beginning with the digit "5" indicate cases in which the server is aware that it has erred or is incapable of performing the request. Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. User agents SHOULD display any included entity to the user. These response codes are applicable to any request method.

Community
  • 1
  • 1
zzk
  • 1,347
  • 9
  • 15
  • 2
    Yes, but the point was I already sent the header of the request. – user1964161 Mar 08 '13 at 23:58
  • o_O.. probably you shouldn't tell the client everything is ok before you're sure it's ok.. – zzk Mar 09 '13 at 00:01
  • 4
    True, however, that is not always possible. For example: If i have a large file that I am transferring and I found the file on my hard drive I will send the "200 OK" header then start streaming the file from the hard drive (without the entire file in main memory) there can be errors while reading the file. – user1964161 Mar 09 '13 at 00:05
  • I have made it so that an error occurring at this point is very unlikely but it still can happen. – user1964161 Mar 09 '13 at 00:06
  • <200 for GET: an entity corresponding to the requested resource is sent in the response;> by definition you should not use 200 if the resource is not 'sent'(i.e.in the http response), but only 'trying to send'. And I don't know why can't you wait until content is already generated to send the http header. – zzk Mar 09 '13 at 00:13
  • 1
    @zzk Here is one example: you are sending out a 100GB file and your disk fails in the middle of the response. – jdb Mar 09 '13 at 00:36
  • in that case, you can at least reset tcp connection.. i don't think it belong to http layer – zzk Mar 09 '13 at 00:39