Add error handling for cds hooks servlet
This commit is contained in:
@@ -44,7 +44,7 @@ public class CdsHooksServlet extends HttpServlet {
|
|||||||
// CORS Pre-flight
|
// CORS Pre-flight
|
||||||
@Override
|
@Override
|
||||||
protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
//ErrorHandling.setAccessControlHeaders(resp, appProperties);
|
ErrorHandling.setAccessControlHeaders(resp, appProperties);
|
||||||
resp.setHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType());
|
resp.setHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType());
|
||||||
resp.setHeader("X-Content-Type-Options", "nosniff");
|
resp.setHeader("X-Content-Type-Options", "nosniff");
|
||||||
resp.setStatus(HttpServletResponse.SC_OK);
|
resp.setStatus(HttpServletResponse.SC_OK);
|
||||||
@@ -59,7 +59,7 @@ public class CdsHooksServlet extends HttpServlet {
|
|||||||
logger.error(request.getRequestURI());
|
logger.error(request.getRequestURI());
|
||||||
throw new ServletException("This servlet is not configured to handle GET requests.");
|
throw new ServletException("This servlet is not configured to handle GET requests.");
|
||||||
}
|
}
|
||||||
//ErrorHandling.setAccessControlHeaders(response, myAppProperties);
|
ErrorHandling.setAccessControlHeaders(response, appProperties);
|
||||||
response.setHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType());
|
response.setHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType());
|
||||||
response.getWriter().println(new GsonBuilder().setPrettyPrinting().create().toJson(getServices()));
|
response.getWriter().println(new GsonBuilder().setPrettyPrinting().create().toJson(getServices()));
|
||||||
}
|
}
|
||||||
@@ -90,7 +90,7 @@ public class CdsHooksServlet extends HttpServlet {
|
|||||||
response.setContentType("text/json;charset=UTF-8");
|
response.setContentType("text/json;charset=UTF-8");
|
||||||
response.getWriter().println(jsonResponse);
|
response.getWriter().println(jsonResponse);
|
||||||
} catch (BaseServerResponseException e) {
|
} catch (BaseServerResponseException e) {
|
||||||
// ErrorHandling.handleError(response, "ERROR: Exception connecting to remote server.", e, myAppProperties);
|
ErrorHandling.handleError(response, "ERROR: Exception connecting to remote server.", e, appProperties);
|
||||||
logger.error(e.toString());
|
logger.error(e.toString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error(e.toString());
|
logger.error(e.toString());
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package ca.uhn.fhir.jpa.starter.cdshooks;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jpa.starter.AppProperties;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||||
|
|
||||||
|
public class ErrorHandling {
|
||||||
|
|
||||||
|
private ErrorHandling() {}
|
||||||
|
|
||||||
|
public static void handleError(HttpServletResponse response, String message,
|
||||||
|
Exception e, AppProperties myAppProperties)
|
||||||
|
throws IOException {
|
||||||
|
setAccessControlHeaders(response, myAppProperties);
|
||||||
|
response.setStatus(500); // This will be overwritten with the correct status code downstream if needed.
|
||||||
|
response.getWriter().println(message);
|
||||||
|
printMessageAndCause(e, response);
|
||||||
|
if (e instanceof BaseServerResponseException) {
|
||||||
|
handleServerResponseException((BaseServerResponseException) e, response);
|
||||||
|
} else if (e.getCause() instanceof BaseServerResponseException) {
|
||||||
|
handleServerResponseException((BaseServerResponseException) e.getCause(), response);
|
||||||
|
}
|
||||||
|
printStackTrack(e, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void handleServerResponseException(BaseServerResponseException e, HttpServletResponse response)
|
||||||
|
throws IOException {
|
||||||
|
switch (e.getStatusCode()) {
|
||||||
|
case 401:
|
||||||
|
case 403:
|
||||||
|
response.getWriter().println("Precondition Failed. Remote FHIR server returned: " + e.getStatusCode());
|
||||||
|
response.getWriter().println(
|
||||||
|
"Ensure that the fhirAuthorization token is set or that the remote server allows unauthenticated access.");
|
||||||
|
response.setStatus(412);
|
||||||
|
break;
|
||||||
|
case 404:
|
||||||
|
response.getWriter().println("Precondition Failed. Remote FHIR server returned: " + e.getStatusCode());
|
||||||
|
response.getWriter().println("Ensure the resource exists on the remote server.");
|
||||||
|
response.setStatus(412);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
response.getWriter().println("Unhandled Error in Remote FHIR server: " + e.getStatusCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printMessageAndCause(Exception e, HttpServletResponse response) throws IOException {
|
||||||
|
if (e.getMessage() != null) {
|
||||||
|
response.getWriter().println(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.getCause() != null && e.getCause().getMessage() != null) {
|
||||||
|
response.getWriter().println(e.getCause().getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printStackTrack(Exception e, HttpServletResponse response) throws IOException {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
e.printStackTrace(new PrintWriter(sw));
|
||||||
|
String exceptionAsString = sw.toString();
|
||||||
|
response.getWriter().println(exceptionAsString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setAccessControlHeaders(HttpServletResponse resp, AppProperties myAppProperties) {
|
||||||
|
if (myAppProperties.getCors() != null) {
|
||||||
|
if (myAppProperties.getCors().getAllow_Credentials()) {
|
||||||
|
resp.setHeader("Access-Control-Allow-Origin",
|
||||||
|
myAppProperties.getCors().getAllowed_origin().stream().findFirst().get());
|
||||||
|
resp.setHeader("Access-Control-Allow-Methods",
|
||||||
|
String.join(", ", Arrays.asList("GET", "HEAD", "POST", "OPTIONS")));
|
||||||
|
resp.setHeader("Access-Control-Allow-Headers",
|
||||||
|
String.join(", ", Arrays.asList("x-fhir-starter", "Origin",
|
||||||
|
"Accept", "X-Requested-With", "Content-Type", "Authorization", "Cache-Control")));
|
||||||
|
resp.setHeader("Access-Control-Expose-Headers",
|
||||||
|
String.join(", ", Arrays.asList("Location", "Content-Location")));
|
||||||
|
resp.setHeader("Access-Control-Max-Age", "86400");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CdsHooksError extends RuntimeException {
|
||||||
|
public CdsHooksError(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,12 @@
|
|||||||
package ca.uhn.fhir.jpa.starter.cdshooks;
|
package ca.uhn.fhir.jpa.starter.cdshooks;
|
||||||
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.springframework.beans.factory.FactoryBean;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.cache.IResourceChangeListenerRegistry;
|
|
||||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.ICdsHooksDaoAuthorizationSvc;
|
import ca.uhn.hapi.fhir.cdshooks.api.ICdsHooksDaoAuthorizationSvc;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.config.CdsHooksConfig;
|
import ca.uhn.hapi.fhir.cdshooks.config.CdsHooksConfig;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.svc.CdsHooksContextBooter;
|
import ca.uhn.hapi.fhir.cdshooks.svc.CdsHooksContextBooter;
|
||||||
|
|||||||
Reference in New Issue
Block a user