eclipse-ee4j / jersey

Eclipse Jersey Project - Read our Wiki:
https://github.com/eclipse-ee4j/jersey/wiki
Other
689 stars 350 forks source link

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

Closed jerseyrobot closed 9 years ago

jerseyrobot 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]

jerseyrobot commented 6 years ago
jerseyrobot commented 9 years ago

@glassfishrobot Commented Reported by mwnorman

jerseyrobot commented 9 years ago

@glassfishrobot Commented @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

jerseyrobot commented 9 years ago

@glassfishrobot Commented 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.

jerseyrobot commented 9 years ago

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

jerseyrobot commented 9 years ago

@glassfishrobot Commented 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

jerseyrobot commented 9 years ago

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

jerseyrobot commented 9 years ago

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

jerseyrobot commented 9 years ago

@glassfishrobot Commented Was assigned to michalgajdos

jerseyrobot commented 7 years ago

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

jerseyrobot commented 9 years ago

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