5

I have an EE6 JAX-RS application that runs on Jboss 7 (EAP 6.4) and handles most of its exceptions and errors internally through an implementation of ExceptionMapper.

There are circumstances, though, (most notably when HTTP Basic Auth fails) when this is not invoked because the error occurs before the application is invoked, and thus the client gets the server's default error page (JBWEB bla bla, HTML with ugly purple colors).

Now in order to catch these "outer" errors I added <error-page> definitions to web.xml like so:

<error-page>
    <location>/error.json</location>
</error-page>
<error-page>
    <error-code>401</error-code>
    <location>/error401.json</location>
</error-page>

The location works fine and I almost get the response I want but the HTTP status code is always 200.

That is annoying, to say the least. How do I get the error page to return its proper error code?

Antares42
  • 1,406
  • 1
  • 15
  • 45
  • Consume the error and return a `Response` utilizing the builder methods of the class. Or use `ExceptionMapper` class. – soufrk May 23 '16 at 13:39
  • What do you mean by consuming the error? You mean write a little servlet / JAX-RS endpoint instead of a static json file? That is what I ended up doing, but it feels kind of wrong: Without any settings, Jboss returns an HTML with the correct HTTP status. When I specify a page in web.xml, Jboss returns that (great) but changes the status code to 200 (why?) – Antares42 May 23 '16 at 13:44
  • No, I meant isn't something like [this](http://stackoverflow.com/questions/4687271/jax-rs-how-to-return-json-and-http-status-code-together) or [this](http://stackoverflow.com/questions/583973/jax-rs-jersey-how-to-customize-error-handling) helping ? – soufrk May 23 '16 at 14:28
  • Sadly no. I already have an ExceptionMapper inside the JAX-RS application that will process any exception that my code could throw. Unfortunately, HTTP Basic authentication (using web.xml and security realms) happens *outside* of JAX-RS, so the Mapper never gets called. – Antares42 May 23 '16 at 20:10

2 Answers2

4

What I ended up with was writing a small web service (instead of a static page) that would give me a JSON response and the correct HTTP status code, plus relevant headers:

<error-page>
    <error-code>401</error-code>
    <location>/error/401</location>
</error-page>

Which calls the service

@Path("/error")
public class ErrorService {

    private static final Map<Integer, String> statusMsg;
    static
    {
        statusMsg = new HashMap<Integer, String>();
        statusMsg.put(401, "Resource requires authentication");
        statusMsg.put(403, "Access denied");
        statusMsg.put(404, "Resource not found");
        statusMsg.put(500, "Internal server error");
    }

    @GET
    @Path("{httpStatus}")
    public Response error(@PathParam("httpStatus") Integer httpStatus) {

        String msg = statusMsg.get(httpStatus);
        if (msg == null)
            msg = "Unexpected error";

        throw new MyWebApplicationException.Builder()
            .status(httpStatus)
            .addError(msg)
            .build();
    }

}

I have an exception class MyWebApplicationException with its own builder pattern that I've already previously used to format all sorts of application errors as JSON using a jax-rs ExceptionMapper.

So now I'm just manualle feeding externally caught errors (like the 401 that happens outside of JAX-RS) through the same channel as well.

Antares42
  • 1,406
  • 1
  • 15
  • 45
0

The intention of error-page mechanism is to show end user something human readable. In case it return some code other than 200 it would be processed by browser in common way (browser's standard error message).

S. Kadakov
  • 861
  • 1
  • 6
  • 15
  • That can't be quite true. Jboss' (i.e. EAP's) default error pages get returned with their correct status codes. If I don't specify an ````, a failed login will get me the purple JBWEB000065 page with HTTP status 401. – Antares42 May 23 '16 at 13:41