diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BillingExceptionJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BillingExceptionJson.java
index a009eb5..181fa6d 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BillingExceptionJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BillingExceptionJson.java
@@ -54,12 +54,13 @@ public class BillingExceptionJson {
this.stackTrace = stackTrace;
}
- public BillingExceptionJson(final Exception exception) {
+ public BillingExceptionJson(final Exception exception, final boolean withStackTrace) {
this(exception.getClass().getName(),
exception instanceof BillingExceptionBase ? ((BillingExceptionBase) exception).getCode() : null,
exception.getLocalizedMessage(),
exception.getCause() == null ? null : exception.getCause().getClass().getName(),
exception.getCause() == null ? null : exception.getCause().getLocalizedMessage(),
+ !withStackTrace ? ImmutableList.<StackTraceElementJson>of() :
Lists.<StackTraceElement, StackTraceElementJson>transform(ImmutableList.<StackTraceElement>copyOf(exception.getStackTrace()),
new Function<StackTraceElement, StackTraceElementJson>() {
@Override
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/mappers/ExceptionMapperBase.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/mappers/ExceptionMapperBase.java
index 7e32c1d..047d76e 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/mappers/ExceptionMapperBase.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/mappers/ExceptionMapperBase.java
@@ -48,6 +48,8 @@ public abstract class ExceptionMapperBase {
private static final Logger log = LoggerFactory.getLogger(ExceptionMapperBase.class);
private static final ObjectMapper mapper = new ObjectMapper();
+ private static final String QUERY_WITH_STACK_TRACE = "withStackTrace";
+
protected Response fallback(final Exception exception, final UriInfo uriInfo) {
if (exception.getCause() == null) {
return buildBadRequestResponse(exception, uriInfo);
@@ -114,7 +116,7 @@ public abstract class ExceptionMapperBase {
log.warn("Conflicting request", e);
final Response.ResponseBuilder responseBuilder = Response.status(Status.CONFLICT);
- serializeException(e, responseBuilder);
+ serializeException(e, uriInfo, responseBuilder);
return responseBuilder.build();
}
@@ -123,7 +125,7 @@ public abstract class ExceptionMapperBase {
log.info("Not found", e);
final Response.ResponseBuilder responseBuilder = Response.status(Status.NOT_FOUND);
- serializeException(e, responseBuilder);
+ serializeException(e, uriInfo, responseBuilder);
return responseBuilder.build();
}
@@ -132,7 +134,7 @@ public abstract class ExceptionMapperBase {
log.warn("Bad request", e);
final Response.ResponseBuilder responseBuilder = Response.status(Status.BAD_REQUEST);
- serializeException(e, responseBuilder);
+ serializeException(e, uriInfo, responseBuilder);
return responseBuilder.build();
}
@@ -142,7 +144,7 @@ public abstract class ExceptionMapperBase {
// TODO Forbidden?
final Response.ResponseBuilder responseBuilder = Response.status(Status.UNAUTHORIZED);
- serializeException(e, responseBuilder);
+ serializeException(e, uriInfo, responseBuilder);
return responseBuilder.build();
}
@@ -151,23 +153,24 @@ public abstract class ExceptionMapperBase {
log.warn("Internal error", e);
final Response.ResponseBuilder responseBuilder = Response.status(Status.INTERNAL_SERVER_ERROR);
- serializeException(e, responseBuilder);
+ serializeException(e, uriInfo, responseBuilder);
return responseBuilder.build();
}
protected Response buildPluginTimeoutResponse(final Exception e, final UriInfo uriInfo) {
final Response.ResponseBuilder responseBuilder = Response.status(Status.ACCEPTED);
- serializeException(e, responseBuilder);
+ serializeException(e, uriInfo, responseBuilder);
return responseBuilder.build();
}
- private void serializeException(final Exception e, final Response.ResponseBuilder responseBuilder) {
- final BillingExceptionJson billingExceptionJson = new BillingExceptionJson(e);
+ private void serializeException(final Exception e, final UriInfo uriInfo, final Response.ResponseBuilder responseBuilder) {
+ final boolean withStackTrace = uriInfo.getQueryParameters() != null && "true".equals(uriInfo.getQueryParameters().getFirst(QUERY_WITH_STACK_TRACE));
+ final BillingExceptionJson billingExceptionJson = new BillingExceptionJson(e, withStackTrace);
try {
final String billingExceptionJsonAsString = mapper.writeValueAsString(billingExceptionJson);
responseBuilder.entity(billingExceptionJsonAsString).type(MediaType.APPLICATION_JSON);
- } catch (JsonProcessingException jsonException) {
+ } catch (final JsonProcessingException jsonException) {
log.warn("Unable to serialize exception", jsonException);
responseBuilder.entity(e.toString()).type(MediaType.TEXT_PLAIN_TYPE);
}
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestBillingExceptionJson.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestBillingExceptionJson.java
index 86b605c..626df42 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestBillingExceptionJson.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestBillingExceptionJson.java
@@ -56,7 +56,7 @@ public class TestBillingExceptionJson extends JaxrsTestSuiteNoDB {
nil.toString();
Assert.fail();
} catch (final NullPointerException e) {
- final BillingExceptionJson exceptionJson = new BillingExceptionJson(e);
+ final BillingExceptionJson exceptionJson = new BillingExceptionJson(e, true);
Assert.assertEquals(exceptionJson.getClassName(), e.getClass().getName());
Assert.assertNull(exceptionJson.getCode());
Assert.assertNull(exceptionJson.getMessage());
@@ -66,6 +66,14 @@ public class TestBillingExceptionJson extends JaxrsTestSuiteNoDB {
Assert.assertEquals(exceptionJson.getStackTrace().get(0).getClassName(), TestBillingExceptionJson.class.getName());
Assert.assertEquals(exceptionJson.getStackTrace().get(0).getMethodName(), "testFromException");
Assert.assertFalse(exceptionJson.getStackTrace().get(0).getNativeMethod());
+
+ final BillingExceptionJson exceptionJsonNoStackTrace = new BillingExceptionJson(e, false);
+ Assert.assertEquals(exceptionJsonNoStackTrace.getClassName(), e.getClass().getName());
+ Assert.assertNull(exceptionJsonNoStackTrace.getCode());
+ Assert.assertNull(exceptionJsonNoStackTrace.getMessage());
+ Assert.assertNull(exceptionJsonNoStackTrace.getCauseClassName());
+ Assert.assertNull(exceptionJsonNoStackTrace.getCauseMessage());
+ Assert.assertTrue(exceptionJsonNoStackTrace.getStackTrace().isEmpty());
}
}
}