javaee / jersey

This is no longer the active Jersey repository. Please see the README.md
http://jersey.github.io
Other
2.87k stars 2.36k forks source link

400 errors generated by a ValidationException are returning default error page instead of the Bean Validation's response entity #2945

Closed glassfishrobot closed 9 years ago

glassfishrobot commented 9 years ago

400 errors generated by a javax.validation.ValidationException are returning (Grizzly's) default error page (html) instead of the Bean Validation's response entity (json). I've tried a ClientResponseFilter and its entityStream also contains the html error page. I have put a test project up on github. I asked on Stackoverflow (http://tinyurl.com/o7oou85) and one of the Grizzly guys says that this is Jersey's behaviour - org.glassfish.jersey.message.internal.CommittingOutputStream#flushBuffer(boolean) - writes JSON error message to the Servlet OutputStream and org.glassfish.jersey.servlet.internal.ResponseWriter#commit() - if data has been written to the response buffer, but not returned to the client (i.e. the response is not committed), the data in the response buffer must be cleared and replaced with the data set by these methods ...

I would like some configuration setting that would allow choice between the default error page or the Bean Validation's response entity.

Environment

GrizzlyHttpServerFactory + Jersey + Bean Validation (jersey-container-grizzly2-servlet/jersey-bean-validation ver 2.12, grizzly-http-server ver 2.3.16, hibernate-validator ver 5.0.0.Final)

Affected Versions

[2.13]

glassfishrobot commented 9 years ago

Reported by mwnorman

glassfishrobot commented 9 years ago

@AdamLindenthal said: Hi mwnorman,

Thanks for submitting the issue. I've just attached your github example to it. And I also edited your description a bit (so that links work etc.), hope you don't mind.

The issue will be now moved to backlog and we will take a look at it in one of the future sprints.

Regards, Adam

glassfishrobot commented 9 years ago

jendib said: This issue seems to also affect custom WebApplicationException (https://jersey.java.net/documentation/2.15/representations.html#d0e6501). I tried all the latest Jersey releases, and this bug was introducted in 2.11 (2.10.1 is OK), if this can help.

glassfishrobot commented 9 years ago

michalgajdos said: Do you still see this issue? I am somehow not able to reproduce it.

glassfishrobot commented 9 years ago

rodierc said: Hi Michael,

As a workaround, I found the combination of these three obscure settings gave me back a REST response that is JSON and not the HTML error pages (at a somewhat high productivity cost.) Perhaps you have this flag set?

In my view the error pages should be a result that is disabled, if you start the GrizzlyHttpServer in code, by default it should return whatever Jersey returns, not filter or alter the output with any HTML pages, simplifying this issue. Turning it on should be one flag.

The most important, and not well documented of them, is setting the custom ErrorrPageGenerator, overriding the default Grizzly Error Page Generator.

This is on Jersey = 2.21, Grizzly = 2.3.22.

<dependency>
            <groupId>org.glassfish.grizzly</groupId>
            <artifactId>grizzly-http-all</artifactId>
            <version>2.3.22</version>
        </dependency>

1. Set an init parameter that is non-obvious "do what you should do by default"

servletRegistration.setInitParameter(ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, "true");

2. Add an 'ErrorPageGenerator', overwriting the default Error Page Genenerator (now basically hacking into Jersey and Grizzly internals, to get it to return JSON errors for a REST Container?)

ErrorPageGenerator epg = new ErrorPageGenerator(){
            @Override
            public String generate(Request request, int status, String reasonPhrase,
                                   String description, Throwable exception) {

                StringBuilder sb = new StringBuilder();

                sb.append(reasonPhrase);

                if (exception != null) {
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    PrintStream ps = new PrintStream(baos);
                    exception.printStackTrace(ps);
                    ps.close();
                    sb.append(new String(baos.toByteArray()));
                }

                // already logged by Exception handlers                 // System.out.println(sb.toString());               return sb.toString();
            }
        };

        server.getServerConfiguration().setDefaultErrorPageGenerator(epg);

3. Return a Response object with Bad Request (which is the 400 code I want exposed to the users, not 200), with a custom object inside containing an error message property:

@Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @PUT
    @Path("/submitOrder")
    public Response sendNewOrder(SubmitOrder order) throws CustomReasonPhraseException {
        log.warn("Order Received via REST: " + order);
        String resultCodeString = null;

        try {
            resultCodeString = OrderSender.getInstance().sendOrder(order);
        } catch (Throwable t) {
            return Response.status(Response.Status.BAD_REQUEST.getStatusCode()).entity(makeErrorResult(t)).build();
        }

        log.warn("Done processing submit order: " + order+" returning success.");
        return Response.ok(makeSuccessResult(resultCodeString)).build();

This seems like a decent size hack, to simply return the results of an Exception inside the server, as a 400/500 error + JSON error message. I tried working with custom exception mappers, but still Grizzly would resolve these to HTML 500 or HTML 400 error pages. Notably returning http response code 0 would surpass these pages, but 400 / 500 is the standard I needed to adhere to.

Thanks for looking, hope it helps, Chris

glassfishrobot commented 9 years ago

jendib said: The issue has been fixed in 2.20 and above. I tested it and it works just fine.

glassfishrobot commented 9 years ago

File: grizzly-error-page-master.zip Attached By: @AdamLindenthal

glassfishrobot commented 9 years ago

Was assigned to michalgajdos

glassfishrobot commented 7 years ago

This issue was imported from java.net JIRA JERSEY-2673

glassfishrobot commented 9 years ago

Marked as fixed on Monday, July 27th 2015, 2:17:20 am