httpservelet response not returning sendError status code
httpservelet response not returning sendError status code
I am trying to determine why a webserver response that initially throws an exception in processing; then returns a 200 OK client side. The details are as follows:
a request is sent to the webserver from the web application and if an error occurs an exception is caught and the relevant code &/or message is returned as follows:
public void dispatchRequest(HttpServletRequest req, HttpServletResponse
res)
{
if (method.equalsIgnoreCase("get")) {
doGet(req, res);
} else {
res.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
return;
}
}
void doGet(HttpServletRequest request, HttpServletResponse response)
throws
IOException,
HTTPServerException {
handleGetClient(request, response);
}
@SuppressWarnings("unchecked")
private void handleGetClient(HttpServletRequest request,
HttpServletResponse
response)
throws IOException, HTTPServerException {
...
} catch (IOException e) {
logger("I/O Error during playback with parameters (additional
parameters logged) {0}: {1}",traceParams,e.toString());
logger(Level.FINER, "I/O Error during playback with parameters {0}:
{1}", parameters, e.getMessage());
logger(Level.FINER, "I/O Error during playback with parameters {0}:
{1}", parameters, e);
sendError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
...
}
protected void sendError(HttpServletResponse response, int errCode) {
response.setContentType("text/plain");
try {
response.sendError(errCode,"ERROR");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
The handleGetClient method handles the process and in the event of an error throws exceptions which are caught. The method then uses the sendError method to set the error code returned and when log debugging I could see that this was set to in this specific error (500). But once the call returns to the dispatchRequest method the httpservletResponse status is actually (200). I cannot see where this happening and why. Initially I thought I could just change the method to int to return the error code but I am limited to the changes I can make on this code.
Any ideas?
4 Answers
4
You could try one of the following:
response.resetBuffer ();
response.setStatus (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.flushBuffer ();
or if you have an error page matching the 500 code in your web.xml:
web.xml
response.reset ();
response.setError (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
You could also consider using an exception mapper, for any generic error, so instead of playing yourself with the error code, you could just throw an exception which would take care of the status code return.
i.e: throw new InternalServerException ("Your message");
throw new InternalServerException ("Your message");
Either your pasted code is missing a piece or the original code does not set the actual error on the response object. Somewhere is the sendError method there should be a line like:
sendError
response.setStatus(errCode);
@vbNewbie Maybe do you have some Filter in place that could be changing the StatusCode?
– DrHopfen
Jun 25 at 10:41
Possibly a return statement might be in the catch block that eventually ends up in normal functioning of sending response. I am only stating a possibility. More you can do is check what is being returned after the request is processed successfully from server (either after exception handling or normal functioning).
Once you have started streaming response to the client, you can no longer change the response code, since it is returned in the first line of response and can never be changed afterwards. Same thing with response headers - once you've started streaming body content, you can't change them.
Now, servlet containers use buffering. This means that you can write some data to response and then change your mind (as @MehdiB. has indicated). But once you have overflown that buffer, the data is written to client (first status code, then headers, then body) and you can no longer change status at this point.
The probable solution here is to avoid writing body until you are sure there are no errors. If your body is long, but you can figure out its full lenght, you can add Content-Length header - in this case client will know if you don't deliver the response in whole without relying on status codes.
I remember in my practice adding servlet filters which will intercept HttpServletResponse to make sure that servlets behave nicely with regards to this constraint.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
I have set the status and tried that and checked the response status but the browser response is always a 200; I logged the response status at several places in the code to confirm the 500 response code but it still delivers a 200. Could jetty be changing this?
– vbNewbie
Jun 25 at 10:34