Added a hook so subclasses of BaseController can customize error messages. (#691)

This commit is contained in:
Diederik Muylwyk 2017-07-13 14:05:19 -04:00 committed by GitHub
parent 1a6b3ea867
commit d7714c6372
2 changed files with 80 additions and 82 deletions

View File

@ -1,37 +1,5 @@
package ca.uhn.fhir.to;
import static org.apache.commons.lang3.StringUtils.defaultString;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.entity.ContentType;
import org.apache.http.message.BasicHeader;
import org.hl7.fhir.dstu3.model.CapabilityStatement;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestComponent;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestResourceComponent;
import org.hl7.fhir.dstu3.model.DecimalType;
import org.hl7.fhir.dstu3.model.Extension;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IDomainResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.thymeleaf.TemplateEngine;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
@ -49,6 +17,31 @@ import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.to.model.HomeRequest;
import ca.uhn.fhir.util.ExtensionConstants;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.entity.ContentType;
import org.apache.http.message.BasicHeader;
import org.hl7.fhir.dstu3.model.CapabilityStatement;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestComponent;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestResourceComponent;
import org.hl7.fhir.dstu3.model.DecimalType;
import org.hl7.fhir.dstu3.model.Extension;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IDomainResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.thymeleaf.TemplateEngine;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;
import static org.apache.commons.lang3.StringUtils.defaultString;
public class BaseController {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseController.class);
@ -298,7 +291,7 @@ public class BaseController {
ourLog.warn("Failed to invoke server", e);
if (e != null) {
theModel.put("errorMsg", "Error: " + e.getMessage());
theModel.put("errorMsg", toDisplayError("Error: " + e.getMessage(), e));
}
return returnsResource;
@ -328,7 +321,7 @@ public class BaseController {
conformance = (Conformance) client.conformance();
} catch (Exception e) {
ourLog.warn("Failed to load conformance statement", e);
theModel.put("errorMsg", "Failed to load conformance statement, error was: " + e.toString());
theModel.put("errorMsg", toDisplayError("Failed to load conformance statement, error was: " + e.toString(), e));
conformance = new Conformance();
}
@ -388,7 +381,7 @@ public class BaseController {
conformance = (ca.uhn.fhir.model.dstu2.resource.Conformance) client.conformance();
} catch (Exception e) {
ourLog.warn("Failed to load conformance statement", e);
theModel.put("errorMsg", "Failed to load conformance statement, error was: " + e.toString());
theModel.put("errorMsg", toDisplayError("Failed to load conformance statement, error was: " + e.toString(), e));
conformance = new ca.uhn.fhir.model.dstu2.resource.Conformance();
}
@ -448,7 +441,7 @@ public class BaseController {
capabilityStatement = client.fetchConformance().ofType(org.hl7.fhir.dstu3.model.CapabilityStatement.class).execute();
} catch (Exception ex) {
ourLog.warn("Failed to load conformance statement", ex);
theModel.put("errorMsg", "Failed to load conformance statement, error was: " + ex.toString());
theModel.put("errorMsg", toDisplayError("Failed to load conformance statement, error was: " + ex.toString(), ex));
}
theModel.put("jsonEncodedConf", getContext(theRequest).newJsonParser().encodeResourceToString(capabilityStatement));
@ -676,7 +669,7 @@ public class BaseController {
} catch (Exception e) {
ourLog.error("Failure during processing", e);
theModelMap.put("errorMsg", "Error during processing: " + e.getMessage());
theModelMap.put("errorMsg", toDisplayError("Error during processing: " + e.getMessage(), e));
}
}
@ -753,4 +746,16 @@ public class BaseController {
BUNDLE, NONE, RESOURCE, TAGLIST
}
/**
* A hook to be overridden by subclasses. The overriding method can modify the error message
* based on its content and/or the related exception.
*
* @param theErrorMsg The original error message to be displayed to the user.
* @param theException The exception that occurred. May be null.
* @return The modified error message to be displayed to the user.
*/
protected String toDisplayError(String theErrorMsg, Exception theException) {
return theErrorMsg;
}
}

View File

@ -1,36 +1,5 @@
package ca.uhn.fhir.to;
import static org.apache.commons.lang3.StringUtils.defaultIfEmpty;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.TreeSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.dstu3.model.CapabilityStatement;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestComponent;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestResourceComponent;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent;
import org.hl7.fhir.dstu3.model.CodeType;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseConformance;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import com.google.gson.stream.JsonWriter;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
@ -58,6 +27,30 @@ import ca.uhn.fhir.to.model.HomeRequest;
import ca.uhn.fhir.to.model.ResourceRequest;
import ca.uhn.fhir.to.model.TransactionRequest;
import ca.uhn.fhir.util.ExtensionConstants;
import com.google.gson.stream.JsonWriter;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.dstu3.model.CapabilityStatement;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestComponent;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestResourceComponent;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseConformance;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.TreeSet;
import static org.apache.commons.lang3.StringUtils.*;
@org.springframework.stereotype.Controller()
public class Controller extends BaseController {
@ -128,13 +121,13 @@ public class Controller extends BaseController {
try {
def = getResourceType(theRequest, theReq);
} catch (ServletException e) {
theModel.put("errorMsg", e.toString());
theModel.put("errorMsg", toDisplayError(e.toString(), e));
return "resource";
}
String id = StringUtils.defaultString(theReq.getParameter("resource-delete-id"));
if (StringUtils.isBlank(id)) {
theModel.put("errorMsg", "No ID specified");
theModel.put("errorMsg", toDisplayError("No ID specified", null));
return "resource";
}
@ -173,7 +166,7 @@ public class Controller extends BaseController {
try {
def = getResourceType(theRequest, theReq);
} catch (ServletException e) {
theModel.put("errorMsg", e.toString());
theModel.put("errorMsg", toDisplayError(e.toString(), e));
return "resource";
}
@ -237,7 +230,7 @@ public class Controller extends BaseController {
if (myConfig.isRefuseToFetchThirdPartyUrls()) {
if (!url.startsWith(theModel.get("base").toString())) {
ourLog.warn(logPrefix(theModel) + "Refusing to load page URL: {}", url);
theModel.put("errorMsg", "Invalid page URL: " + url);
theModel.put("errorMsg", toDisplayError("Invalid page URL: " + url, null));
return "result";
}
}
@ -279,12 +272,12 @@ public class Controller extends BaseController {
try {
def = getResourceType(theRequest, theReq);
} catch (ServletException e) {
theModel.put("errorMsg", e.toString());
theModel.put("errorMsg", toDisplayError(e.toString(), e));
return "resource";
}
String id = StringUtils.defaultString(theReq.getParameter("id"));
if (StringUtils.isBlank(id)) {
theModel.put("errorMsg", "No ID specified");
theModel.put("errorMsg", toDisplayError("No ID specified", null));
return "resource";
}
ResultType returnsResource = ResultType.RESOURCE;
@ -391,7 +384,7 @@ public class Controller extends BaseController {
try {
query = search.forResource((Class<? extends IBaseResource>) getResourceType(theRequest, theReq).getImplementingClass());
} catch (ServletException e) {
theModel.put("errorMsg", e.toString());
theModel.put("errorMsg", toDisplayError(e.toString(), e));
return "resource";
}
clientCodeJsonWriter.name("resource");
@ -463,7 +456,7 @@ public class Controller extends BaseController {
String limit = theReq.getParameter("resource-search-limit");
if (isNotBlank(limit)) {
if (!limit.matches("[0-9]+")) {
theModel.put("errorMsg", "Search limit must be a numeric value.");
theModel.put("errorMsg", toDisplayError("Search limit must be a numeric value.", null));
return "resource";
}
int limitInt = Integer.parseInt(limit);
@ -534,12 +527,12 @@ public class Controller extends BaseController {
} else if (body.startsWith("<")) {
// XML content
} else {
theModel.put("errorMsg", "Message body does not appear to be a valid FHIR resource instance document. Body should start with '<' (for XML encoding) or '{' (for JSON encoding).");
theModel.put("errorMsg", toDisplayError("Message body does not appear to be a valid FHIR resource instance document. Body should start with '<' (for XML encoding) or '{' (for JSON encoding).", null));
return "home";
}
} catch (DataFormatException e) {
ourLog.warn("Failed to parse bundle", e);
theModel.put("errorMsg", "Failed to parse transaction bundle body. Error was: " + e.getMessage());
theModel.put("errorMsg", toDisplayError("Failed to parse transaction bundle body. Error was: " + e.getMessage(), e));
return "home";
}
@ -587,7 +580,7 @@ public class Controller extends BaseController {
String body = validate ? theReq.getParameter("resource-validate-body") : theReq.getParameter("resource-create-body");
if (isBlank(body)) {
theModel.put("errorMsg", "No message body specified");
theModel.put("errorMsg", toDisplayError("No message body specified", null));
return;
}
@ -602,12 +595,12 @@ public class Controller extends BaseController {
resource = getContext(theRequest).newXmlParser().parseResource(type, body);
client.setEncoding(EncodingEnum.XML);
} else {
theModel.put("errorMsg", "Message body does not appear to be a valid FHIR resource instance document. Body should start with '<' (for XML encoding) or '{' (for JSON encoding).");
theModel.put("errorMsg", toDisplayError("Message body does not appear to be a valid FHIR resource instance document. Body should start with '<' (for XML encoding) or '{' (for JSON encoding).", null));
return;
}
} catch (DataFormatException e) {
ourLog.warn("Failed to parse resource", e);
theModel.put("errorMsg", "Failed to parse message body. Error was: " + e.getMessage());
theModel.put("errorMsg", toDisplayError("Failed to parse message body. Error was: " + e.getMessage(), e));
return;
}