From f16fd44f39ba2c13292865c16110b0ce1c3a8b1a Mon Sep 17 00:00:00 2001 From: robdu Date: Tue, 15 Sep 2020 18:28:44 +0200 Subject: [PATCH] remedy poor exception handling with java reflection --- build.gradle | 2 +- .../codingchili/core/protocol/Protocol.java | 18 ++++++++++++++++-- .../core/protocol/AnnotatedRouter.java | 7 +++++++ .../core/protocol/ProtocolTest.java | 17 +++++++++++++++-- .../core/protocol/SimpleBuilderRouter.java | 6 ++++++ .../codingchili/core/storage/QueryTest.java | 3 +-- 6 files changed, 46 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 153371b3..e165bdc3 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'java' apply plugin: 'idea' apply plugin: 'maven' -project.version = "1.3.4" +project.version = "1.3.5" project.group = 'com.github.codingchili.chili-core' subprojects { diff --git a/core/main/java/com/codingchili/core/protocol/Protocol.java b/core/main/java/com/codingchili/core/protocol/Protocol.java index a6f4394e..e65287c7 100644 --- a/core/main/java/com/codingchili/core/protocol/Protocol.java +++ b/core/main/java/com/codingchili/core/protocol/Protocol.java @@ -1,5 +1,6 @@ package com.codingchili.core.protocol; +import com.codingchili.core.context.CoreRuntimeException; import io.vertx.core.Future; import io.vertx.core.buffer.Buffer; @@ -226,12 +227,25 @@ private void wrap(String route, Receiver handler, Method method, Ro @SuppressWarnings("unchecked") private E invokeMethod(Method method, Object instance, Object argument) { try { - return (E) method.invoke(instance, argument); + if (method.getParameterCount() == 0) { + return (E) method.invoke(instance); + } else { + return (E) method.invoke(instance, argument); + } } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); + throw throwAny(e.getCause()); // thrown inside throwAny method. } } + public static RuntimeException throwAny(final Throwable throwable) { + Protocol.throwAsUnchecked(throwable); + throw new AssertionError("Internal error in exception rewrite."); + } + + public static void throwAsUnchecked(Throwable throwable) throws T { + throw (T) throwable; + } + /** * Registers a handler for the given route. *

diff --git a/core/test/java/com/codingchili/core/protocol/AnnotatedRouter.java b/core/test/java/com/codingchili/core/protocol/AnnotatedRouter.java index e1ba5c47..8c4873b0 100644 --- a/core/test/java/com/codingchili/core/protocol/AnnotatedRouter.java +++ b/core/test/java/com/codingchili/core/protocol/AnnotatedRouter.java @@ -1,5 +1,7 @@ package com.codingchili.core.protocol; +import com.codingchili.core.context.CoreException; +import com.codingchili.core.context.CoreRuntimeException; import io.vertx.core.Future; import com.codingchili.core.listener.CoreHandler; @@ -51,6 +53,11 @@ public void customRoleOnRoute(Request request) { request.write(customRoleOnRoute); } + @Api(PUBLIC) + public void throwMappedException(Request request) { + throw new CoreRuntimeException("Core runtime exception retains message"); + } + @Override public void handle(Request request) { // unused: protocol is called directly by tests. diff --git a/core/test/java/com/codingchili/core/protocol/ProtocolTest.java b/core/test/java/com/codingchili/core/protocol/ProtocolTest.java index 76e6c69a..dc7126e3 100644 --- a/core/test/java/com/codingchili/core/protocol/ProtocolTest.java +++ b/core/test/java/com/codingchili/core/protocol/ProtocolTest.java @@ -1,5 +1,6 @@ package com.codingchili.core.protocol; +import com.codingchili.core.context.CoreRuntimeException; import com.codingchili.core.listener.CoreHandler; import com.codingchili.core.listener.Request; import com.codingchili.core.protocol.exception.AuthorizationRequiredException; @@ -36,7 +37,8 @@ public abstract class ProtocolTest { static final String specialRoute = "specialRoute"; static final String CUSTOM_ROLE = "CUSTOM_ROLE"; private static final String MISSING = "missing"; - private static final int ROUTE_COUNT = 7; + public static final String mappedException = "throwMappedException"; + private static final int ROUTE_COUNT = 8; static { RoleMap.put(CUSTOM_ROLE, new RoleType() { @@ -70,7 +72,6 @@ public void setUp() { @Test public void testHandlerMissing(TestContext test) throws Exception { Async async = test.async(); - try { protocol.get(MISSING); test.fail("Should throw handler missing exception."); @@ -133,6 +134,18 @@ public void testCustomRouteName(TestContext test) { protocol.get(specialRoute, PUBLIC).submit(onWrite(test.async(), specialRoute)); } + @Test + public void testMappedException(TestContext test) { + Async async = test.async(); + try { + protocol.get(mappedException, PUBLIC) + .submit(onWrite(async, mappedException)); + test.fail("Did not throw exception."); + } catch (CoreRuntimeException e) { + async.complete(); + } + } + @Test public void testMultipleUsersHasAccess(TestContext test) { protocol.get(multipleUserRoute, USER).submit(onWrite(test.async(), multipleUserRoute)); diff --git a/core/test/java/com/codingchili/core/protocol/SimpleBuilderRouter.java b/core/test/java/com/codingchili/core/protocol/SimpleBuilderRouter.java index c514e52f..2fb8a83f 100644 --- a/core/test/java/com/codingchili/core/protocol/SimpleBuilderRouter.java +++ b/core/test/java/com/codingchili/core/protocol/SimpleBuilderRouter.java @@ -1,5 +1,6 @@ package com.codingchili.core.protocol; +import com.codingchili.core.context.CoreRuntimeException; import io.vertx.core.Future; import com.codingchili.core.listener.CoreHandler; @@ -26,6 +27,7 @@ public SimpleBuilderRouter() { .use(adminRoleRoute, this::adminRoleRoute, ADMIN) .use(userRoleRoute, this::userRoleRoute, USER) .use(specialRoute, this::customRouteName) + .use(mappedException, this::throwMappedExcepetion) .use(multipleUserRoute, this::multipleUserRoute, USER, ADMIN) .use(customRoleOnRoute, this::customRoleOnRoute, RoleMap.get(CUSTOM_ROLE)); } @@ -42,6 +44,10 @@ public Protocol getProtocol() { return protocol; } + public void throwMappedExcepetion(Request request) { + throw new CoreRuntimeException("mapped runtime exception"); + } + public void documentedRoute(Request request) { request.write(documentedRoute); } diff --git a/core/test/java/com/codingchili/core/storage/QueryTest.java b/core/test/java/com/codingchili/core/storage/QueryTest.java index 9407d9ea..fa8713e5 100644 --- a/core/test/java/com/codingchili/core/storage/QueryTest.java +++ b/core/test/java/com/codingchili/core/storage/QueryTest.java @@ -46,7 +46,7 @@ public void setUp() { @Test public void testGenerateQueryString(TestContext test) { - String query = new Query().on("cat.type") + String query = new Query<>().on("cat.type") .in("siamese", "perser", "ragdoll") .and("cat.color").equalTo("white") .or("cat.lifestyle").in("amphibians", "wateranimal").matches("[water].*") @@ -57,7 +57,6 @@ public void testGenerateQueryString(TestContext test) { .toString(); } - @Test public void testParseQueryString(TestContext test) { QueryBuilder builder = new Query<>();