|
12 | 12 | import org.slf4j.Logger; |
13 | 13 |
|
14 | 14 | import io.jooby.Context; |
| 15 | +import io.jooby.Reified; |
15 | 16 | import io.jooby.SneakyThrows; |
16 | 17 | import io.jooby.jsonrpc.*; |
17 | 18 |
|
|
32 | 33 | public class JsonRpcExecutor implements JsonRpcChain { |
33 | 34 | private final Map<String, JsonRpcService> services; |
34 | 35 | private final Map<Class<?>, Logger> loggers; |
35 | | - private final JsonRpcExceptionTranslator exceptionTranslator; |
36 | 36 | private final Exception parseError; |
37 | 37 |
|
38 | 38 | /** |
39 | 39 | * Constructs a new executor for a single JSON-RPC request. |
40 | 40 | * |
41 | | - * @param loggers A map of loggers keyed by service class. |
42 | 41 | * @param services A map of registered JSON-RPC services keyed by method name. |
43 | | - * @param exceptionTranslator The translator used to map standard Throwables to JSON-RPC error |
44 | | - * codes. |
| 42 | + * @param loggers A map of service loggers keyed by service class. |
45 | 43 | * @param parseError Any exception that occurred during the initial JSON parsing phase. |
46 | 44 | */ |
47 | 45 | public JsonRpcExecutor( |
48 | | - Map<Class<?>, Logger> loggers, |
49 | | - Map<String, JsonRpcService> services, |
50 | | - JsonRpcExceptionTranslator exceptionTranslator, |
51 | | - Exception parseError) { |
| 46 | + Map<String, JsonRpcService> services, Map<Class<?>, Logger> loggers, Exception parseError) { |
52 | 47 | this.services = services; |
53 | 48 | this.loggers = loggers; |
54 | | - this.exceptionTranslator = exceptionTranslator; |
55 | 49 | this.parseError = parseError; |
56 | 50 | } |
57 | 51 |
|
@@ -93,13 +87,13 @@ public JsonRpcExecutor( |
93 | 87 | throw new JsonRpcException( |
94 | 88 | JsonRpcErrorCode.METHOD_NOT_FOUND, "Method not found: " + fullMethod); |
95 | 89 | } catch (Throwable cause) { |
96 | | - return toRpcResponse(log, request, cause); |
| 90 | + return toRpcResponse(ctx, log, request, cause); |
97 | 91 | } |
98 | 92 | } |
99 | 93 |
|
100 | 94 | private Optional<JsonRpcResponse> toRpcResponse( |
101 | | - Logger log, JsonRpcRequest request, Throwable ex) { |
102 | | - var code = exceptionTranslator.toErrorCode(ex); |
| 95 | + Context ctx, Logger log, JsonRpcRequest request, Throwable ex) { |
| 96 | + var code = toErrorCode(ctx, ex); |
103 | 97 | log(log, request, code, ex); |
104 | 98 |
|
105 | 99 | if (SneakyThrows.isFatal(ex)) { |
@@ -172,4 +166,18 @@ private void log(Logger log, JsonRpcRequest request, JsonRpcErrorCode code, Thro |
172 | 166 | } |
173 | 167 | } |
174 | 168 | } |
| 169 | + |
| 170 | + public JsonRpcErrorCode toErrorCode(Context ctx, Throwable cause) { |
| 171 | + if (cause instanceof JsonRpcException rpcException) { |
| 172 | + return rpcException.getCode(); |
| 173 | + } |
| 174 | + // Attempt to look up any user-defined exception mappings from the registry |
| 175 | + Map<Class<?>, JsonRpcErrorCode> customErrorMapping = |
| 176 | + ctx.require(Reified.map(Class.class, JsonRpcErrorCode.class)); |
| 177 | + return customErrorMapping.entrySet().stream() |
| 178 | + .filter(entry -> entry.getKey().isInstance(cause)) |
| 179 | + .findFirst() |
| 180 | + .map(Map.Entry::getValue) |
| 181 | + .orElseGet(() -> JsonRpcErrorCode.of(ctx.getRouter().errorCode(cause))); |
| 182 | + } |
175 | 183 | } |
0 commit comments