Fix #207 - Confusing error message parsing invalid contained resources

This commit is contained in:
jamesagnew 2015-08-17 20:46:56 -04:00
parent c2fba2ce21
commit 6941f92090
8 changed files with 64 additions and 29 deletions

View File

@ -1123,9 +1123,9 @@ public class JsonParser extends BaseParser implements IParser {
JsonObject nextObject = (JsonObject) theJsonVal;
boolean preResource = false;
if (theState.isPreResource()) {
String resType = nextObject.getString("resourceType");
String resType = nextObject.getString("resourceType", null);
if (isBlank(resType)) {
throw new DataFormatException("Missing 'resourceType' from resource");
throw new DataFormatException("Missing required element 'resourceType' from JSON resource object, unable to parse");
}
theState.enteringNewElement(null, resType);
preResource = true;

View File

@ -328,7 +328,7 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
}
/**
* Subclasses may override this method (but should also call super.{@link #populateActionRequestDetailsForInterceptor(ActionRequestDetails, Object[])) to provide method specifics to the
* Subclasses may override this method (but should also call super.{@link #populateActionRequestDetailsForInterceptor(RequestDetails, ActionRequestDetails, Object[])} to provide method specifics to the
* interceptors.
*
* @param theRequestDetails

View File

@ -9,6 +9,8 @@ import java.util.Map;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import ca.uhn.fhir.rest.server.IResourceProvider;
/*
* #%L
* HAPI FHIR - Core Library
@ -32,6 +34,18 @@ import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
/**
* Base class for RESTful client and server exceptions. RESTful client methods will only throw exceptions which are subclasses of this exception type, and RESTful server methods should also only call
* subclasses of this exception type.
* <p>
* HAPI provides a number of subclasses of BaseServerResponseException, and each one corresponds to a specific
* HTTP status code. For example, if a {@link IResourceProvider resource provider} method throws
* {@link ResourceNotFoundException}, this is a signal to the server that an <code>HTTP 404</code> should
* be returned to the client.
* </p>
* <p>
* <b>See:</b> A complete list of available exceptions is in the <a href="./package-summary.html">package summary</a>.
* If an exception doesn't exist for a condition you want to represent, let us know by filing an
* <a href="https://github.com/jamesagnew/hapi-fhir/issues">issue in our tracker</a>. You may also
* use {@link UnclassifiedServerFailureException} to represent any error code you want.
* </p>
*/
public abstract class BaseServerResponseException extends RuntimeException {

View File

@ -17,6 +17,8 @@ import ca.uhn.fhir.util.ElementUtil;
@ResourceDef(name = "DiagnosticReport")
public class MyDiagnosticReportWithBoundCodeExtension extends DiagnosticReport {
private static final long serialVersionUID = 1L;
public static final String SP_IMAGING_STUDY = "ImagingStudy";
/**

View File

@ -6,4 +6,6 @@ import ca.uhn.fhir.model.dstu.resource.Organization;
@ResourceDef()
public class MyOrganization extends Organization {
private static final long serialVersionUID = 1L;
}

View File

@ -15,6 +15,8 @@ import ca.uhn.fhir.model.primitive.StringDt;
@ResourceDef()
public class MyPatient extends Patient {
private static final long serialVersionUID = 1L;
@Child(name = "importantDates", max = Child.MAX_UNLIMITED)
@Extension(url = "http://example.com/dontuse#importantDates", definedLocally = false, isModifier = true)
@Description(shortDefinition = "Some dates of note for the patient")

View File

@ -3,11 +3,7 @@ package ca.uhn.fhir.parser;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.*;
import java.io.IOException;
import java.util.ArrayList;
@ -299,7 +295,6 @@ public class JsonParserDstu2Test {
}
/**
* Fixing #89
*/
@ -319,7 +314,6 @@ public class JsonParserDstu2Test {
//@formatter:on
}
/**
* #158
*/
@ -328,10 +322,10 @@ public class JsonParserDstu2Test {
TagList tagList = new TagList();
tagList.addTag(null, null, null);
tagList.addTag(null, null, "Label");
Patient p = new Patient();
ResourceMetadataKeyEnum.TAG_LIST.put(p, tagList);
String encoded = ourCtx.newJsonParser().encodeResourceToString(p);
assertThat(encoded, not(containsString("tag")));
}
@ -344,10 +338,10 @@ public class JsonParserDstu2Test {
TagList tagList = new TagList();
tagList.addTag("scheme", "code", null);
tagList.addTag(null, null, "Label");
Patient p = new Patient();
ResourceMetadataKeyEnum.TAG_LIST.put(p, tagList);
String encoded = ourCtx.newJsonParser().encodeResourceToString(p);
assertThat(encoded, containsString("tag"));
assertThat(encoded, containsString("scheme"));
@ -415,7 +409,7 @@ public class JsonParserDstu2Test {
Patient p = new Patient();
p.setId("123");
p.addName().addFamily("ABC");
assertThat(ourCtx.newJsonParser().encodeResourceToString(p), stringContainsInOrder("123", "ABC"));
assertThat(ourCtx.newJsonParser().setOmitResourceId(true).encodeResourceToString(p), containsString("ABC"));
assertThat(ourCtx.newJsonParser().setOmitResourceId(true).encodeResourceToString(p), not(containsString("123")));
@ -444,7 +438,7 @@ public class JsonParserDstu2Test {
Medication m = (Medication) parsed.getEntries().get(1).getResource();
assertEquals("http://example.com/base/Medication/example", m.getId().getValue());
assertSame(((ResourceReferenceDt)p.getMedication()).getResource(), m);
assertSame(((ResourceReferenceDt) p.getMedication()).getResource(), m);
String reencoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeBundleToString(parsed);
ourLog.info(reencoded);
@ -474,9 +468,9 @@ public class JsonParserDstu2Test {
ca.uhn.fhir.model.dstu2.resource.Bundle parsed = ourCtx.newXmlParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, content);
MedicationPrescription p = (MedicationPrescription) parsed.getEntry().get(0).getResource();
assertEquals("#med", ((ResourceReferenceDt)p.getMedication()).getReference().getValue());
assertEquals("#med", ((ResourceReferenceDt) p.getMedication()).getReference().getValue());
Medication m = (Medication) ((ResourceReferenceDt)p.getMedication()).getResource();
Medication m = (Medication) ((ResourceReferenceDt) p.getMedication()).getResource();
assertNotNull(m);
assertEquals("#med", m.getId().getValue());
assertEquals(1, p.getContained().getContainedResources().size());
@ -514,8 +508,8 @@ public class JsonParserDstu2Test {
Medication m = (Medication) parsed.getEntry().get(1).getResource();
assertEquals("http://example.com/base/Medication/example", m.getId().getValue());
assertEquals("Medication/example", ((ResourceReferenceDt)p.getMedication()).getReference().getValue());
assertSame(((ResourceReferenceDt)p.getMedication()).getResource(), m);
assertEquals("Medication/example", ((ResourceReferenceDt) p.getMedication()).getReference().getValue());
assertSame(((ResourceReferenceDt) p.getMedication()).getResource(), m);
String reencoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(parsed);
ourLog.info(reencoded);
@ -554,8 +548,8 @@ public class JsonParserDstu2Test {
Medication m = (Medication) parsed.getEntries().get(1).getResource();
assertEquals("http://example.com/base/Medication/example", m.getId().getValue());
assertEquals("Medication/example", ((ResourceReferenceDt)p.getMedication()).getReference().getValue());
assertSame(((ResourceReferenceDt)p.getMedication()).getResource(), m);
assertEquals("Medication/example", ((ResourceReferenceDt) p.getMedication()).getReference().getValue());
assertSame(((ResourceReferenceDt) p.getMedication()).getResource(), m);
String reencoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeBundleToString(parsed);
ourLog.info(reencoded);
@ -665,12 +659,12 @@ public class JsonParserDstu2Test {
" ]" +
"}";
//@formatter:on
ca.uhn.fhir.model.dstu2.resource.Bundle parsed = ourCtx.newJsonParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, input);
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(parsed);
ourLog.info(encoded);
assertEquals("urn:uuid:180f219f-97a8-486d-99d9-ed631fe4fc57", parsed.getEntry().get(0).getResource().getId().getValue());
assertEquals("urn:uuid:", parsed.getEntry().get(0).getResource().getId().getBaseUrl());
assertEquals("180f219f-97a8-486d-99d9-ed631fe4fc57", parsed.getEntry().get(0).getResource().getId().getIdPart());
@ -807,6 +801,22 @@ public class JsonParserDstu2Test {
assertNull(ResourceMetadataKeyEnum.PROFILES.get(patient));
}
/**
* See #207
*/
@Test
public void testParseResourceWithInvalidType() {
String input = "{" + "\"resourceType\":\"Patient\"," + "\"contained\":[" + " {" + " \"rezType\":\"Organization\"" + " }" + " ]" + "}";
IParser jsonParser = ourCtx.newJsonParser().setPrettyPrint(true);
try {
jsonParser.parseResource(input);
fail();
} catch (DataFormatException e) {
assertEquals("Missing required element 'resourceType' from JSON resource object, unable to parse", e.getMessage());
}
}
/**
* See #163
*/
@ -829,10 +839,10 @@ public class JsonParserDstu2Test {
String bundleText = jsonParser.encodeResourceToString(bundle);
ourLog.info(bundleText);
ca.uhn.fhir.model.dstu2.resource.Bundle reincarnatedBundle = jsonParser.parseResource (ca.uhn.fhir.model.dstu2.resource.Bundle.class, bundleText);
Patient reincarnatedPatient = (Patient) reincarnatedBundle.getEntry().get(0).getResource();
ca.uhn.fhir.model.dstu2.resource.Bundle reincarnatedBundle = jsonParser.parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, bundleText);
Patient reincarnatedPatient = (Patient) reincarnatedBundle.getEntry().get(0).getResource();
assertEquals("Patient", patient.getId().getResourceType());
assertEquals("Patient", reincarnatedPatient.getId().getResourceType());
}

View File

@ -88,6 +88,11 @@
of the appropriate error code for the exception being thrown. Thanks to Nagesh Bashyam
for reporting!
</action>
<action type="fix" issue="207">
Fix issue in JSON parser where invalid contained resources (missing
a resourceType element) fail to parse with a confusing NullPointerException.
Thanks to GitHub user @hugosoares for reporting!
</action>
</release>
<release version="1.1" date="2015-07-13">
<action type="add">