diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/OperationOutcomeUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/OperationOutcomeUtil.java index c910e4ce4758..8905dd2f06cd 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/OperationOutcomeUtil.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/OperationOutcomeUtil.java @@ -36,6 +36,7 @@ import org.hl7.fhir.instance.model.api.ICompositeType; import org.hl7.fhir.instance.model.api.IPrimitiveType; +import java.util.ArrayList; import java.util.List; import static org.apache.commons.lang3.StringUtils.isNotBlank; @@ -114,6 +115,18 @@ public static String getFirstIssueDiagnostics(FhirContext theCtx, IBaseOperation return getIssueStringPart(theCtx, theOutcome, "diagnostics", 0); } + public static List getAllIssueDiagnostics(FhirContext theCtx, IBaseOperationOutcome theOutcome) { + int nIssues = OperationOutcomeUtil.getIssueCount(theCtx, theOutcome); + + List issueStrings = new ArrayList<>(); + for (int i = 0; i < nIssues; i++) { + String diag = OperationOutcomeUtil.getIssueDiagnostics(theCtx, theOutcome, i); + issueStrings.add(diag); + } + + return issueStrings; + } + public static String getIssueDiagnostics(FhirContext theCtx, IBaseOperationOutcome theOutcome, int theIndex) { return getIssueStringPart(theCtx, theOutcome, "diagnostics", theIndex); } diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/util/OperationOutcomeUtilTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/util/OperationOutcomeUtilTest.java new file mode 100644 index 000000000000..aa7e119a9b0c --- /dev/null +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/util/OperationOutcomeUtilTest.java @@ -0,0 +1,41 @@ +package ca.uhn.fhir.util; + +import ca.uhn.fhir.context.FhirContext; +import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.CALLS_REAL_METHODS; + +class OperationOutcomeUtilTest { + @org.junit.jupiter.params.ParameterizedTest + @org.junit.jupiter.params.provider.ValueSource(ints = {0, 1, 2}) + void testGetAllIssueDiagnostics_various_items(int numDiagnostics) { + // Arrange + FhirContext ctx = Mockito.mock(FhirContext.class); + IBaseOperationOutcome outcome = Mockito.mock(IBaseOperationOutcome.class); + List knownDiagnostics = java.util.stream.IntStream.range(0, numDiagnostics) + .mapToObj(i -> "diag" + i) + .collect(java.util.stream.Collectors.toList()); + + try (MockedStatic operationUtils = Mockito.mockStatic(OperationOutcomeUtil.class, CALLS_REAL_METHODS)) { + operationUtils.when(() -> OperationOutcomeUtil.getIssueCount(any(), any())).thenReturn(knownDiagnostics.size()); + operationUtils.when(() -> OperationOutcomeUtil.getIssueDiagnostics(any(), any(), anyInt())) + .thenAnswer(invocation -> { + int idx = invocation.getArgument(2); + return knownDiagnostics.get(idx); + }); + + // Act + List resultDiagnostics = OperationOutcomeUtil.getAllIssueDiagnostics(ctx, outcome); + + // Assert + assertEquals(knownDiagnostics, resultDiagnostics); + } + } +} diff --git a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/interceptor/validation/RepositoryValidatingInterceptor.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/interceptor/validation/RepositoryValidatingInterceptor.java index 31f928669154..41b9db9fecc9 100644 --- a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/interceptor/validation/RepositoryValidatingInterceptor.java +++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/interceptor/validation/RepositoryValidatingInterceptor.java @@ -153,9 +153,10 @@ private boolean isPlaceholderResource(IBaseResource theNewResource) { protected void handleFailure(IRepositoryValidatingRule.RuleEvaluation theOutcome) { if (theOutcome.getOperationOutcome() != null) { - String firstIssue = - OperationOutcomeUtil.getFirstIssueDiagnostics(myFhirContext, theOutcome.getOperationOutcome()); - throw new PreconditionFailedException(Msg.code(574) + firstIssue, theOutcome.getOperationOutcome()); + List allIssues = + OperationOutcomeUtil.getAllIssueDiagnostics(myFhirContext, theOutcome.getOperationOutcome()); + String concatenatedIssues = String.join("\n", allIssues); + throw new PreconditionFailedException(Msg.code(574) + concatenatedIssues, theOutcome.getOperationOutcome()); } throw new PreconditionFailedException(Msg.code(575) + theOutcome.getFailureDescription()); }