This is an automated email from the ASF dual-hosted git repository. myrle pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/fineract-cn-api.git
commit 8514adc3e8f28c7e19246576eadb21e8b32d50fc Author: myrle-krantz <[email protected]> AuthorDate: Tue Mar 28 11:14:56 2017 +0200 Adding the ability to define exceptions via ThrowException which accept a string as a parameter. --- .../mifos/core/api/util/AnnotatedErrorDecoder.java | 57 ++++++++++-------- .../core/api/util/AnnotatedErrorDecoderTest.java | 68 +++++++++++++++++++--- 2 files changed, 92 insertions(+), 33 deletions(-) diff --git a/src/main/java/io/mifos/core/api/util/AnnotatedErrorDecoder.java b/src/main/java/io/mifos/core/api/util/AnnotatedErrorDecoder.java index af7387c..0a23b40 100644 --- a/src/main/java/io/mifos/core/api/util/AnnotatedErrorDecoder.java +++ b/src/main/java/io/mifos/core/api/util/AnnotatedErrorDecoder.java @@ -62,26 +62,28 @@ class AnnotatedErrorDecoder implements ErrorDecoder { } private RuntimeException getAlternative(final String methodKey, final Response response) { - try { - final String bodyText = Util.toString(response.body().asReader()); - - if (response.status() == HttpStatus.BAD_REQUEST.value()) { - return new IllegalArgumentException(bodyText); - } else if (response.status() == HttpStatus.FORBIDDEN.value()) { - return new InvalidTokenException(bodyText); - } else if (response.status() == HttpStatus.NOT_FOUND.value()) { - return new NotFoundException(bodyText); - } else if (response.status() == HttpStatus.INTERNAL_SERVER_ERROR.value()) { - return new InternalServerError(bodyText); - } else { - return FeignException.errorStatus(methodKey, response); - } - - } catch (IOException e) { - + final String bodyText = stringifyBody(response); + + if (response.status() == HttpStatus.BAD_REQUEST.value()) { + return new IllegalArgumentException(bodyText); + } else if (response.status() == HttpStatus.FORBIDDEN.value()) { + return new InvalidTokenException(bodyText); + } else if (response.status() == HttpStatus.NOT_FOUND.value()) { + return new NotFoundException(bodyText); + } else if (response.status() == HttpStatus.INTERNAL_SERVER_ERROR.value()) { + return new InternalServerError(bodyText); + } else { return FeignException.errorStatus(methodKey, response); + } + } + private String stringifyBody(final Response response) { + try { + if (response.body() != null) + return Util.toString(response.body().asReader()); + } catch (IOException ignored) { } + return null; } private Optional<ThrowsException> getMatchingAnnotation( @@ -123,16 +125,23 @@ class AnnotatedErrorDecoder implements ErrorDecoder { final ThrowsException throwsExceptionAnnotations) { try { try { - final Constructor<? extends RuntimeException> oneArgumentConstructor = + final Constructor<? extends RuntimeException> oneResponseArgumentConstructor = throwsExceptionAnnotations.exception().getConstructor(Response.class); - return Optional.of(oneArgumentConstructor.newInstance(response)); + return Optional.of(oneResponseArgumentConstructor.newInstance(response)); } catch (final NoSuchMethodException e) { - - final Constructor<? extends RuntimeException> noArgumentConstructor = - throwsExceptionAnnotations.exception().getConstructor(); - - return Optional.of(noArgumentConstructor.newInstance()); + try { + final Constructor<? extends RuntimeException> noArgumentConstructor = + throwsExceptionAnnotations.exception().getConstructor(); + + return Optional.of(noArgumentConstructor.newInstance()); + } + catch (final NoSuchMethodException e2) { + final Constructor<? extends RuntimeException> noStringArgumentConstructor = + throwsExceptionAnnotations.exception().getConstructor(String.class); + + return Optional.of(noStringArgumentConstructor.newInstance(stringifyBody(response))); + } } } catch (final InvocationTargetException | IllegalAccessException diff --git a/src/test/java/io/mifos/core/api/util/AnnotatedErrorDecoderTest.java b/src/test/java/io/mifos/core/api/util/AnnotatedErrorDecoderTest.java index 7dc1104..fc53e4c 100644 --- a/src/test/java/io/mifos/core/api/util/AnnotatedErrorDecoderTest.java +++ b/src/test/java/io/mifos/core/api/util/AnnotatedErrorDecoderTest.java @@ -26,6 +26,7 @@ import org.junit.runners.Parameterized; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -48,37 +49,48 @@ public class AnnotatedErrorDecoderTest { final Response emptyInternalServerErrorResponse = Response.builder() .status(HttpStatus.INTERNAL_SERVER_ERROR.value()) - .reason("blah") + .body("blah", Charset.defaultCharset()) .headers(Collections.emptyMap()) .build(); final Response emptyBadRequestResponse = Response.builder() .status(HttpStatus.BAD_REQUEST.value()) - .reason("blah") + .body("blah", Charset.defaultCharset()) + .headers(Collections.emptyMap()) + .build(); + + final Response emptyBadRequestResponseWithNoBody = Response.builder() + .status(HttpStatus.BAD_REQUEST.value()) + .headers(Collections.emptyMap()) + .build(); + + final Response emptyNotFoundRequestResponse = Response.builder() + .status(HttpStatus.NOT_FOUND.value()) + .body("blah", Charset.defaultCharset()) .headers(Collections.emptyMap()) .build(); final Response emptyConflictResponse = Response.builder() .status(HttpStatus.CONFLICT.value()) - .reason("blah") + .body("blah", Charset.defaultCharset()) .headers(Collections.emptyMap()) .build(); final Response emptyIAmATeapotResponse = Response.builder() .status(HttpStatus.I_AM_A_TEAPOT.value()) - .reason("blah") + .body("blah", Charset.defaultCharset()) .headers(Collections.emptyMap()) .build(); final Response emptyUnauthorizedResponse = Response.builder() .status(HttpStatus.UNAUTHORIZED.value()) - .reason("blah") + .body("blah", Charset.defaultCharset()) .headers(Collections.emptyMap()) .build(); final Response emptyForbiddenResponse = Response.builder() .status(HttpStatus.FORBIDDEN.value()) - .reason("blah") + .body("blah", Charset.defaultCharset()) .headers(Collections.emptyMap()) .build(); @@ -91,7 +103,10 @@ public class AnnotatedErrorDecoderTest { Feign.configKey(OneMethodInterface.class, OneMethodInterface.class.getMethod("method")); final String onceAnnotatedMethodKey = - Feign.configKey(OneMethodOneAnnotationInterface.class, OneMethodOneAnnotationInterface.class.getMethod("method")); + Feign.configKey(OneMethodOneAnnotationInterface.class, OneMethodOneAnnotationInterface.class.getMethod("method")); + + final String onceAnnotatedWithStringExceptionMethodKey = + Feign.configKey(OneMethodOneAnnotationStringParameteredExceptionInterface.class, OneMethodOneAnnotationStringParameteredExceptionInterface.class.getMethod("method")); ret.add(new TestCase("Methodless interface") .clazz(MethodlessInterface.class) @@ -135,12 +150,31 @@ public class AnnotatedErrorDecoderTest { .response(emptyBadRequestResponse) .expectedResult(new ParameterlessException())); + ret.add(new TestCase("Interface with one method that has one annotation containing an exception which accepts a string parameter.") + .clazz(OneMethodOneAnnotationStringParameteredExceptionInterface.class) + .methodKey(onceAnnotatedWithStringExceptionMethodKey) + .response(emptyBadRequestResponse) + .expectedResult(new StringParameteredException("blah"))); + ret.add(new TestCase("Bad request on an interface in which bad request isn't mapped.") .clazz(AnnotationlessInterface.class) .methodKey(annotationlessMethodKey) .response(emptyBadRequestResponse) .expectedResult(new IllegalArgumentException("blah"))); + ret.add(new TestCase("Bad request with no body on an interface in which bad request isn't mapped.") + .clazz(AnnotationlessInterface.class) + .methodKey(annotationlessMethodKey) + .response(emptyBadRequestResponseWithNoBody) + .expectedResult(new IllegalArgumentException((String)null))); + + + ret.add(new TestCase("Not found request on an interface in which not found request isn't mapped.") + .clazz(AnnotationlessInterface.class) + .methodKey(annotationlessMethodKey) + .response(emptyNotFoundRequestResponse) + .expectedResult(new NotFoundException("blah"))); + ret.add(new TestCase("Request with invalid token.") .clazz(OneMethodOneAnnotationInterface.class) .methodKey(onceAnnotatedMethodKey) @@ -199,6 +233,14 @@ public class AnnotatedErrorDecoderTest { void method(); } + + private interface OneMethodOneAnnotationStringParameteredExceptionInterface { + + @SuppressWarnings("unused") + @ThrowsException(status = HttpStatus.BAD_REQUEST, exception = StringParameteredException.class) + void method(); + } + private static class TestCase { private final String name; @@ -272,10 +314,18 @@ public class AnnotatedErrorDecoderTest { } } + private static class StringParameteredException extends RuntimeException { + + @SuppressWarnings("WeakerAccess") + public StringParameteredException(final String response) { + super(response); + } + } + private static class WrongParameteredException extends RuntimeException { - public WrongParameteredException(final String message) { - super(message); + public WrongParameteredException(final Integer message) { + super(message.toString()); } } } -- To stop receiving notification emails like this one, please contact [email protected].
