Skip to content

Commit

Permalink
DefaultExceptionMapper
Browse files Browse the repository at this point in the history
Signed-off-by: Maxim Nesen <maxim.nesen@oracle.com>
  • Loading branch information
senivam committed Oct 1, 2021
1 parent b9479ae commit fc31ad6
Show file tree
Hide file tree
Showing 17 changed files with 120 additions and 71 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package org.glassfish.jersey.internal;

import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;

public class DefaultExceptionMapper implements ExceptionMapper<Throwable> {
@Override
public Response toResponse(Throwable exception) {
return (exception instanceof WebApplicationException)
? processWebApplicationException((WebApplicationException) exception)
: processDefaultException(exception);
}

private static Response processWebApplicationException(WebApplicationException exception) {
return (exception.getResponse() == null)
? processDefaultException(exception)
: exception.getResponse();
}

private static Response processDefaultException(Throwable exception) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(exception.getMessage()).build();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -58,6 +58,8 @@ public class ExceptionMapperFactory implements ExceptionMappers {

private static final Logger LOGGER = Logger.getLogger(ExceptionMapperFactory.class.getName());

private static final ExceptionMapper<Throwable> DEFAULT_EXCEPTION_MAPPER = new DefaultExceptionMapper();

/**
* Configurator which initializes and register {@link ExceptionMappers} instance into {@link InjectionManager} and
* {@link BootstrapBag}.
Expand Down Expand Up @@ -127,7 +129,7 @@ private <T extends Throwable> ExceptionMapper<T> find(final Class<T> type, final
}
}
}
return mapper;
return mapper == null ? (ExceptionMapper<T>) DEFAULT_EXCEPTION_MAPPER : mapper;
}

/**
Expand Down
5 changes: 0 additions & 5 deletions core-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,6 @@
<artifactId>jakarta.validation-api</artifactId>
</dependency>

<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</dependency>

<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-osgi</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -54,6 +54,7 @@

import jakarta.inject.Provider;

import org.glassfish.jersey.internal.DefaultExceptionMapper;
import org.glassfish.jersey.internal.guava.Preconditions;
import org.glassfish.jersey.internal.inject.InjectionManager;
import org.glassfish.jersey.internal.inject.Injections;
Expand Down Expand Up @@ -496,14 +497,20 @@ private Response mapException(final Throwable originalThrowable) throws Throwabl

do {
final Throwable throwable = wrap.getCurrent();
// internal mapping
if (throwable instanceof HeaderValueException) {
if (((HeaderValueException) throwable).getContext() == HeaderValueException.Context.INBOUND) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
}
if (wrap.isInMappable() || throwable instanceof WebApplicationException) {
// in case ServerProperties.PROCESSING_RESPONSE_ERRORS_ENABLED is true, allow
// wrapped MessageBodyProviderNotFoundException to propagate
if (runtime.processResponseErrors && throwable instanceof InternalServerErrorException
&& throwable.getCause() instanceof MessageBodyProviderNotFoundException) {
throw throwable;
}
Response waeResponse = null;
Response waeResponse;

if (throwable instanceof WebApplicationException) {
final WebApplicationException webApplicationException = (WebApplicationException) throwable;
Expand All @@ -512,10 +519,11 @@ private Response mapException(final Throwable originalThrowable) throws Throwabl
processingContext.routingContext().setMappedThrowable(throwable);

waeResponse = webApplicationException.getResponse();
if (waeResponse.hasEntity()) {
LOGGER.log(Level.FINE, LocalizationMessages
.EXCEPTION_MAPPING_WAE_ENTITY(waeResponse.getStatus()), throwable);
return waeResponse;
if (waeResponse != null) {
LOGGER.log(Level.FINE, waeResponse.hasEntity()
? LocalizationMessages.EXCEPTION_MAPPING_WAE_ENTITY(waeResponse.getStatus())
: LocalizationMessages.EXCEPTION_MAPPING_WAE_NO_ENTITY(waeResponse.getStatus()),
throwable);
}
}

Expand All @@ -527,7 +535,7 @@ private Response mapException(final Throwable originalThrowable) throws Throwabl
try {
final Response mappedResponse = mapper.toResponse(throwable);

if (tracingLogger.isLogEnabled(ServerTraceEvent.EXCEPTION_MAPPING)) {
if (isTracingLoggingEnabled(mapper, throwable, tracingLogger)) {
tracingLogger.logDuration(ServerTraceEvent.EXCEPTION_MAPPING,
timestamp, mapper, throwable, throwable.getLocalizedMessage(),
mappedResponse != null ? mappedResponse.getStatusInfo() : "-no-response-");
Expand Down Expand Up @@ -561,19 +569,6 @@ private Response mapException(final Throwable originalThrowable) throws Throwabl
return Response.serverError().build();
}
}

if (waeResponse != null) {
LOGGER.log(Level.FINE, LocalizationMessages
.EXCEPTION_MAPPING_WAE_NO_ENTITY(waeResponse.getStatus()), throwable);

return waeResponse;
}
}
// internal mapping
if (throwable instanceof HeaderValueException) {
if (((HeaderValueException) throwable).getContext() == HeaderValueException.Context.INBOUND) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
}

if (!wrap.isInMappable() || !wrap.isWrapped()) {
Expand Down Expand Up @@ -740,6 +735,14 @@ private void release(final ContainerResponse responseContext) {
processingContext.triggerEvent(RequestEvent.Type.FINISHED);
}
}

private static boolean isTracingLoggingEnabled(ExceptionMapper mapper, Throwable throwable, TracingLogger tracingLogger) {
boolean defaultLoggingState = mapper instanceof DefaultExceptionMapper
&& throwable instanceof WebApplicationException;
return !defaultLoggingState
&& tracingLogger.isLogEnabled(ServerTraceEvent.EXCEPTION_MAPPING);

}
}

private static class AsyncResponder implements AsyncContext, ContainerResponseWriter.TimeoutHandler, CompletionCallback {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -558,12 +558,14 @@ public void testMapResponseErrorForMbw() throws Exception {
/**
* Test that un-mapped response errors are tried to be processed only once (MBW).
*/
@Test(expected = ExecutionException.class)
@Test
public void testMapCyclicResponseErrorForMbw() throws Exception {
final ApplicationHandler handler = new ApplicationHandler(MapResponseErrorApplication.class);

final ContainerRequest context = RequestContextBuilder.from("/foobar", "GET").build();

handler.apply(context).get();
final ContainerResponse containerResponse = handler.apply(context).get();
assertEquals(500, containerResponse.getStatus());
assertEquals("Cannot do that!", containerResponse.getEntity());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -35,6 +35,7 @@

import jakarta.inject.Singleton;

import org.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
Expand Down Expand Up @@ -71,6 +72,7 @@ public void testCompletionCallback() throws ExecutionException, InterruptedExcep
}

@Test
@Ignore("since JAXRS 3.1 failure is not processed by callbacks")
public void testCompletionFail() throws ExecutionException, InterruptedException {
final Flags flags = new Flags();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -318,11 +318,7 @@ public Response apply(final ContainerRequestContext request) {
});
resourceConfig.registerResources(rb.build());
final ApplicationHandler application = new ApplicationHandler(resourceConfig);
try {
application.apply(RequestContextBuilder.from("/test", "GET").build()).get().getStatus();
Assert.fail("should throw an exception");
} catch (final Exception e) {
// ok
}
int status = application.apply(RequestContextBuilder.from("/test", "GET").build()).get().getStatus();
Assert.assertEquals(500, status);
}
}
6 changes: 0 additions & 6 deletions ext/entity-filtering/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,6 @@
<scope>provided</scope>
</dependency>

<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.glassfish.jersey.test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
Expand Down
4 changes: 0 additions & 4 deletions ext/wadl-doclet/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,6 @@
<artifactId>jersey-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
5 changes: 0 additions & 5 deletions incubator/declarative-linking/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,6 @@
<artifactId>jakarta.xml.bind-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.el</groupId>
<artifactId>jakarta.el-api</artifactId>
Expand Down
5 changes: 0 additions & 5 deletions test-framework/core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,6 @@
<artifactId>jersey-container-servlet-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>${servlet5.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -46,6 +46,7 @@
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.TestProperties;

import org.junit.Ignore;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
Expand Down Expand Up @@ -105,13 +106,15 @@ public void testResumeMappedException() throws Exception {
}

@Test
@Ignore("since 3.1 nothing is being thrown")
public void testResumeRuntimeException() throws Exception {
testResumeException("resumeRuntimeException", null);

assertThat(getLastLoggedRecord().getThrown(), instanceOf(RuntimeException.class));
}

@Test
@Ignore("since 3.1 nothing is being thrown")
public void testResumeCheckedException() throws Exception {
testResumeException("resumeCheckedException", null);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -76,14 +76,12 @@ protected Application configure() {
public void testRuntime() throws Exception {
final Response response = target().path("runtime").request().get();
assertEquals(500, response.getStatus());
assertEquals(getLastLoggedRecord().getThrown().getClass(), MyRuntimeException.class);
}

@Test
public void testChecked() throws Exception {
final Response response = target().path("checked").request().get();
assertEquals(500, response.getStatus());
assertEquals(getLastLoggedRecord().getThrown().getClass(), MyCheckedException.class);
}

@Provider
Expand Down Expand Up @@ -123,8 +121,6 @@ public ExceptionLoggingTestPOJO entity() {
public void testReaderFails() throws Exception {
final Response response = target().path("resource/entity").request().get();
assertEquals(500, response.getStatus());

assertEquals(getLastLoggedRecord().getThrown().getMessage(), "test");
}

static class ExceptionLoggingTestPOJO {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -34,6 +34,7 @@ public Jersey2176App(boolean setStatusOverSendError) {
property(ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, setStatusOverSendError);
register(MyWriterInterceptor.class);
register(Issue2176ReproducerResource.class);
register(Jersey2176ExceptionMapper.class);
}

public boolean isSetStatusOverSendError() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package org.glassfish.jersey.tests.integration.jersey2176;

import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;

public class Jersey2176ExceptionMapper implements ExceptionMapper<Throwable> {
@Override
public Response toResponse(Throwable exception) {
if (exception instanceof WebApplicationException) {
return ((WebApplicationException) exception).getResponse();
}
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(exception).build();
}
}
Loading

0 comments on commit fc31ad6

Please sign in to comment.