From 33686267f9deeeca24200c49747868880f9c7808 Mon Sep 17 00:00:00 2001 From: Holger Knoche Date: Wed, 27 Mar 2024 08:09:29 +0100 Subject: [PATCH] Added support for unmapped exceptions --- .../json/consumer/ConsumerOperationProxy.java | 11 +++++- .../apievolution/json/JsonMappingTest.java | 37 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/gutta-apievolution-json/src/main/java/gutta/apievolution/json/consumer/ConsumerOperationProxy.java b/gutta-apievolution-json/src/main/java/gutta/apievolution/json/consumer/ConsumerOperationProxy.java index fb456d4..0a27b12 100644 --- a/gutta-apievolution-json/src/main/java/gutta/apievolution/json/consumer/ConsumerOperationProxy.java +++ b/gutta-apievolution-json/src/main/java/gutta/apievolution/json/consumer/ConsumerOperationProxy.java @@ -166,8 +166,15 @@ public R invokeOperation(P parameterObject, OnUnrepresentableValue onUnrepres String exceptionTypeName = determineSpecificTypeId(responseNode).orElseThrow(NoSuchElementException::new); Class exceptionTypeRepresentation = this.exceptionTypeMap.get(exceptionTypeName); - MappedExceptionData exceptionData = (MappedExceptionData) objectMapper.treeToValue(responseNode, exceptionTypeRepresentation); - throw exceptionData.createMappedException(); + if (exceptionTypeRepresentation != null) { + // If the exception type is mapped, create the appropriate exception + MappedExceptionData exceptionData = (MappedExceptionData) objectMapper.treeToValue(responseNode, exceptionTypeRepresentation); + throw exceptionData.createMappedException(); + } else { + // Otherwise, treat the exception as an unrepresentable value + JsonNode resultNode = onUnrepresentableValue.throwExceptionOrReturnDefaultNode(); + return objectMapper.treeToValue(resultNode, this.resultTypeRepresentation); + } } else { // Otherwise, return the value return objectMapper.treeToValue(responseNode, this.resultTypeRepresentation); diff --git a/gutta-apievolution-json/src/test/java/gutta/apievolution/json/JsonMappingTest.java b/gutta-apievolution-json/src/test/java/gutta/apievolution/json/JsonMappingTest.java index ac94bf1..f55fe0b 100644 --- a/gutta-apievolution-json/src/test/java/gutta/apievolution/json/JsonMappingTest.java +++ b/gutta-apievolution-json/src/test/java/gutta/apievolution/json/JsonMappingTest.java @@ -16,6 +16,7 @@ import gutta.apievolution.json.consumer.ConsumerSuperType; import gutta.apievolution.json.consumer.ConsumerTestException; import gutta.apievolution.json.consumer.ConsumerTestExceptionData; +import gutta.apievolution.json.consumer.UnrepresentableValueException; import gutta.apievolution.json.provider.MappableProviderTestException; import gutta.apievolution.json.provider.ProviderEnum; import gutta.apievolution.json.provider.ProviderMonoToPolySubTypeA; @@ -175,6 +176,18 @@ void embeddedMonoToPolyTypeMapping() { assertNotSame(parameter, result); assertEquals(parameter, result); } + + /** + * Test case: The provider throws an exception, but the consumer does not expect one. This results in an unrepresentable value. + */ + @Test + void providerThrowsExceptionButConsumerDoesNotExpectOne() { + OpWithUnmappedExceptionProviderProxy providerProxy = new OpWithUnmappedExceptionProviderProxy(); + RequestRouter requestRouter = new SimpleJsonRequestRouter(providerProxy); + + OpWithUnmappedExceptionConsumerProxy consumerProxy = new OpWithUnmappedExceptionConsumerProxy(requestRouter); + assertThrows(UnrepresentableValueException.class, () -> consumerProxy.invokeOperation(new ConsumerParameter())); + } private abstract static class ConsumerOperationProxyTemplate extends ConsumerOperationProxy { @@ -308,6 +321,30 @@ protected ProviderResult invokeOperation(ProviderParameter parameter) { } + private static class OpWithUnmappedExceptionConsumerProxy extends ConsumerOperationProxyTemplate { + + public OpWithUnmappedExceptionConsumerProxy(RequestRouter router) { + super("opWithUnmappedException", "ConsumerParameter", "ConsumerResult", ConsumerResult.class, Collections.emptySet(), router); + } + + } + + private static class OpWithUnmappedExceptionProviderProxy extends ProviderOperationProxyTemplate { + + public OpWithUnmappedExceptionProviderProxy() { + super("opWithUnmappedException", "ProviderParameter" , "ProviderResult", ProviderParameter.class); + } + + @Override + protected ProviderResult invokeOperation(ProviderParameter parameter) { + ProviderTestException exceptionData = new ProviderTestException(); + exceptionData.setExceptionField(1234); + + throw new MappableProviderTestException(exceptionData); + } + + } + private static class MonoToPolyMappingConsumerProxy extends ConsumerOperationProxyTemplate { public MonoToPolyMappingConsumerProxy(RequestRouter router) {