@Override public RpcCallException decodeException(ContentResponse response) throws RpcCallException { try { if (response != null) { JsonObject json = (JsonObject) new JsonParser().parse(response.getContentAsString()); JsonElement error = json.get("error"); if (error != null) { return RpcCallException.fromJson(error.toString()); } } } catch (Exception ex) { logger.warn("Caught exception decoding protobuf response exception", ex); throw new RpcCallException(RpcCallException.Category.InternalServerError, RpcCallExceptionDecoder.exceptionToString(ex)); } return null; }
public static JsonRpcResponse fromString(String rawResponse) { JsonParser parser = new JsonParser(); JsonObject response = parser.parse(rawResponse).getAsJsonObject(); JsonElement id = response.get("id"); JsonElement errorElement = response.get("error"); int responseStatus = HttpServletResponse.SC_OK; String error; if (! (errorElement instanceof JsonNull)) { if (errorElement instanceof JsonObject) { error = errorElement.toString(); // try parsing it into RpcCallException to get the HttpStatus from there RpcCallException rpcEx = RpcCallException.fromJson(error); if (rpcEx != null) { responseStatus = rpcEx.getCategory().getHttpStatus(); JsonElement resultElement = response.get("result"); return new JsonRpcResponse(id, resultElement == null ? JsonNull.INSTANCE : resultElement, errorElement, responseStatus); } } error = errorElement.getAsString(); if (StringUtils.isNotBlank(error)) { responseStatus = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; } } JsonElement resultElement = response.get("result"); return new JsonRpcResponse(id, resultElement == null ? JsonNull.INSTANCE : resultElement, errorElement, responseStatus); }
@Test public void testFromJson_ErrorWithoutCategory() { String error = "{\"id\":\"com.sixt.service.foobar\",\"code\":500,\"message\":\"error message\",\"status\":\"Internal Server Error\"}"; RpcCallException ex = RpcCallException.fromJson(error); assertThat(ex.getCategory()).isEqualTo(RpcCallException.Category.InternalServerError); }
@Test public void testFromJson_ErrorWithDetailInsteadOfMessage() { String error = "{\"id\":\"com.sixt.service.foobar\",\"code\":500,\"detail\":\"error message\",\"status\":\"Internal Server Error\"}"; RpcCallException ex = RpcCallException.fromJson(error); assertThat(ex.getCategory()).isEqualTo(RpcCallException.Category.InternalServerError); assertThat(ex.getMessage()).isEqualTo("error message"); }
@Test public void testFromInvalidJson() { String error = "invalid json"; RpcCallException ex = RpcCallException.fromJson(error); assertThat(ex).isNull(); }
@Override public RpcCallException decodeException(ContentResponse response) throws RpcCallException { try { if (response != null) { byte[] data = response.getContent(); if (ArrayUtils.isEmpty(data)) { logger.warn("Unable to decode: empty response received"); return new RpcCallException(RpcCallException.Category.InternalServerError, "Empty response received"); } ProtobufRpcResponse pbResponse = new ProtobufRpcResponse(data); String error = pbResponse.getErrorMessage(); if (error != null) { return RpcCallException.fromJson(error); } } } catch (Exception ex) { logger.warn("Caught exception decoding protobuf response exception", ex); throw new RpcCallException(RpcCallException.Category.InternalServerError, RpcCallExceptionDecoder.exceptionToString(ex)); } return null; }
@Test public void testFromJson_CategoryNotANumber() { String error = "{\"sxerror\":\"1\",\"source\":\"go.micro.client\",\"category\":\"not-a-number\"}"; RpcCallException ex = RpcCallException.fromJson(error); assertThat(ex).isNotNull(); assertThat(ex.getCategory()).isEqualTo(RpcCallException.Category.InternalServerError); // Switch to default Category when }
@Test public void testFromJson_CategoryAsNull() { String error = "{\"sxerror\":\"1\",\"source\":\"go.micro.client\",\"category\":null}"; RpcCallException ex = RpcCallException.fromJson(error); assertThat(ex).isNotNull(); assertThat(ex.getCategory()).isEqualTo(RpcCallException.Category.InternalServerError); // Switch to default Category when }
@Test public void testFromJson_CategoryAsFloatingPoint() { String error = "{\"sxerror\":\"1\",\"source\":\"go.micro.client\",\"category\":\1.2345}"; RpcCallException ex = RpcCallException.fromJson(error); assertThat(ex).isNotNull(); assertThat(ex.getCategory()).isEqualTo(RpcCallException.Category.InternalServerError); // Switch to default Category when }
@Test public void testFromJson_CategoryAsObject() { String error = "{\"sxerror\":\"1\",\"source\":\"go.micro.client\",\"category\":{}}"; RpcCallException ex = RpcCallException.fromJson(error); assertThat(ex).isNotNull(); assertThat(ex.getCategory()).isEqualTo(RpcCallException.Category.InternalServerError); // Switch to default Category when }
@Test public void testFromJson_mediumBadData() { String error = "{\"sxerror\":\"1\",\"source\":\"go.micro.client\",\"category\":408,\"code\":\"unexpected_error\",\"message\":\"call timeout: context deadline exceeded\",\"data\":\"'*errors.Error' with error '{\\\"id\\\":\\\"go.micro.client\\\",\\\"code\\\":408,\\\"detail\\\":\\\"call timeout: context deadline exceeded\\\",\\\"status\\\":\\\"Request Timeout\\\"}' cannot be mapped to a known representation. Data: \\u0026errors.Error{Id:\\\"go.micro.client\\\", Code:408, Detail:\\\"call timeout: context deadline exceeded\\\", Status:\\\"Request Timeout\\\"}\",\"retriable\":false}"; RpcCallException ex = RpcCallException.fromJson(error); assertThat(ex).isNotNull(); assertThat(ex.getCategory()).isEqualTo(RpcCallException.Category.InternalServerError); // Switch to default Category when assertThat(ex.getErrorCode()).isEqualTo("unexpected_error"); assertThat(ex.getMessage()).isEqualTo("call timeout: context deadline exceeded"); assertThat(ex.getData()).isNotNull(); assertThat(ex.isRetriable()).isFalse(); }
@Test public void testJsonEncodingDecoding() throws Exception { RpcCallException exception = new RpcCallException(RpcCallException.Category.BadRequest, "You fool!").withData("my data").withErrorCode("SERVICE_PROTOBUF_ENUM"). withRetriable(true).withSource("com.sixt.service.foobar"); String json = exception.toString(); assertThat(json).isEqualTo("{\"category\":400,\"message\":\"You fool!\"," + "\"source\":\"com.sixt.service.foobar\",\"code\":\"SERVICE_PROTOBUF_ENUM\"," + "\"data\":\"my data\",\"retriable\":true}"); RpcCallException.fromJson(json); }