From b0154139617456eeb815511b68e2b8584286180c Mon Sep 17 00:00:00 2001 From: Clayton Bodendein Date: Sun, 22 Oct 2017 13:48:02 -0500 Subject: [PATCH 1/2] Fixes issue #768 so that when DataFormatExceptions are thrown when using AbstractJaxRsProviders, the stacktrace will be included in the OperationOutcome details only if AbstractJaxRsProvider#withStrackTrace() is configured to return true --- .../java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java index 5ba4d6a3a54..632a42935c8 100644 --- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java +++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java @@ -81,7 +81,7 @@ public abstract class AbstractJaxRsProvider implements IRestfulServerDefaults { private IBaseOperationOutcome createOutcome(final DataFormatException theException) { final IBaseOperationOutcome oo = OperationOutcomeUtil.newInstance(getFhirContext()); - final String detailsValue = theException.getMessage() + "\n\n" + ExceptionUtils.getStackTrace(theException); + final String detailsValue = theException.getMessage() + (this.withStackTrace() ? "\n\n" + ExceptionUtils.getStackTrace(theException) : ""); OperationOutcomeUtil.addIssue(getFhirContext(), oo, ERROR, detailsValue, null, PROCESSING); return oo; } From d0e747d6ecf29fc1ed08dbb3a47853f22c815844 Mon Sep 17 00:00:00 2001 From: Clayton Bodendein Date: Sun, 22 Oct 2017 22:20:48 -0500 Subject: [PATCH 2/2] Fixed issue #768 in a different way by wrapping the DataFormatException as an InvalidRequestException so that it still gets sent as a 400 response but now DataFormatException stacktraces can now be conditionally sent based on the ExceptionHandlingInterceptor#setReturnStackTracesForExceptionTypes(Class...) configuration --- .../exceptions/InvalidRequestException.java | 4 ++++ .../fhir/jaxrs/server/AbstractJaxRsProvider.java | 15 --------------- .../interceptor/ExceptionHandlingInterceptor.java | 7 ++++++- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/InvalidRequestException.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/InvalidRequestException.java index 31a51f292ab..e56d3abd620 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/InvalidRequestException.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/InvalidRequestException.java @@ -47,6 +47,10 @@ public class InvalidRequestException extends BaseServerResponseException { public InvalidRequestException(String theMessage) { super(STATUS_CODE, theMessage); } + + public InvalidRequestException(Throwable theCause) { + super(STATUS_CODE, theCause); + } /** * Constructor diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java index 632a42935c8..a0194aa1451 100644 --- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java +++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java @@ -26,8 +26,6 @@ import java.util.Map.Entry; import javax.ws.rs.core.*; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.exception.ExceptionUtils; -import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.api.AddProfileTagEnum; @@ -35,12 +33,9 @@ import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsExceptionInterceptor; import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsResponseException; import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest; import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest.Builder; -import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.server.*; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; -import ca.uhn.fhir.util.OperationOutcomeUtil; /** * This is the abstract superclass for all jaxrs providers. It contains some defaults implementing @@ -79,13 +74,6 @@ public abstract class AbstractJaxRsProvider implements IRestfulServerDefaults { CTX = ctx; } - private IBaseOperationOutcome createOutcome(final DataFormatException theException) { - final IBaseOperationOutcome oo = OperationOutcomeUtil.newInstance(getFhirContext()); - final String detailsValue = theException.getMessage() + (this.withStackTrace() ? "\n\n" + ExceptionUtils.getStackTrace(theException) : ""); - OperationOutcomeUtil.addIssue(getFhirContext(), oo, ERROR, detailsValue, null, PROCESSING); - return oo; - } - /** * DEFAULT = AddProfileTagEnum.NEVER */ @@ -241,9 +229,6 @@ public abstract class AbstractJaxRsProvider implements IRestfulServerDefaults { throws IOException { if (theException instanceof JaxRsResponseException) { return new JaxRsExceptionInterceptor().convertExceptionIntoResponse(theRequest, (JaxRsResponseException) theException); - } else if (theException instanceof DataFormatException) { - return new JaxRsExceptionInterceptor().convertExceptionIntoResponse(theRequest, new JaxRsResponseException( - new InvalidRequestException(theException.getMessage(), createOutcome((DataFormatException) theException)))); } else { return new JaxRsExceptionInterceptor().convertExceptionIntoResponse(theRequest, new JaxRsExceptionInterceptor().convertException(this, theException)); diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/ExceptionHandlingInterceptor.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/ExceptionHandlingInterceptor.java index 55d61dc93e7..da2bba0e053 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/ExceptionHandlingInterceptor.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/ExceptionHandlingInterceptor.java @@ -32,6 +32,8 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import ca.uhn.fhir.parser.DataFormatException; +import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import org.apache.commons.lang3.exception.ExceptionUtils; import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; @@ -99,7 +101,10 @@ public class ExceptionHandlingInterceptor extends InterceptorAdapter { @Override public BaseServerResponseException preProcessOutgoingException(RequestDetails theRequestDetails, Throwable theException, HttpServletRequest theServletRequest) throws ServletException { BaseServerResponseException retVal; - if (!(theException instanceof BaseServerResponseException)) { + if (theException instanceof DataFormatException) { + // Wrapping the DataFormatException as an InvalidRequestException so that it gets sent back to the client as a 400 response. + retVal = new InvalidRequestException(theException); + } else if (!(theException instanceof BaseServerResponseException)) { retVal = new InternalErrorException(theException); } else { retVal = (BaseServerResponseException) theException;