mirror of https://github.com/dapr/java-sdk.git
Adds error payload to DaprException. (#1009)
* Adds error payload to DaprException. Signed-off-by: Artur Souza <asouza.pro@gmail.com> * Keep having http payload in exception message. Signed-off-by: Artur Souza <asouza.pro@gmail.com> * Fix example output. Signed-off-by: Artur Souza <asouza.pro@gmail.com> * Lint. Signed-off-by: Artur Souza <asouza.pro@gmail.com> * Fix test. Signed-off-by: Artur Souza <asouza.pro@gmail.com> --------- Signed-off-by: Artur Souza <asouza.pro@gmail.com>
This commit is contained in:
parent
a3cc1384b5
commit
81e6c4d907
|
|
@ -19,11 +19,6 @@ import io.dapr.exceptions.DaprErrorDetails;
|
|||
import io.dapr.exceptions.DaprException;
|
||||
import io.dapr.utils.TypeRef;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 1. Build and install jars:
|
||||
* mvn clean install
|
||||
|
|
@ -45,10 +40,11 @@ public class Client {
|
|||
} catch (DaprException exception) {
|
||||
System.out.println("Error code: " + exception.getErrorCode());
|
||||
System.out.println("Error message: " + exception.getMessage());
|
||||
System.out.println("Reason: " + exception.getStatusDetails().get(
|
||||
System.out.println("Reason: " + exception.getErrorDetails().get(
|
||||
DaprErrorDetails.ErrorDetailType.ERROR_INFO,
|
||||
"reason",
|
||||
TypeRef.STRING));
|
||||
System.out.println("Error payload size: " + exception.getPayload().length);
|
||||
}
|
||||
}
|
||||
System.out.println("Done");
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ public class Client {
|
|||
DaprErrorDetails.ErrorDetailType.ERROR_INFO,
|
||||
"reason",
|
||||
TypeRef.STRING));
|
||||
System.out.println("Error's payload size: " + exception.getPayload().length);
|
||||
}
|
||||
}
|
||||
System.out.println("Done");
|
||||
|
|
@ -66,6 +67,7 @@ expected_stdout_lines:
|
|||
- '== APP == Error code: INVALID_ARGUMENT'
|
||||
- '== APP == Error message: INVALID_ARGUMENT: pubsub unknown_pubsub is not found'
|
||||
- '== APP == Reason: DAPR_PUBSUB_NOT_FOUND'
|
||||
- '== APP == Error payload size: 116'
|
||||
background: true
|
||||
sleep: 5
|
||||
-->
|
||||
|
|
@ -84,6 +86,8 @@ Once running, the State Client Example should print the output as follows:
|
|||
== APP == Error message: ERR_PUBSUB_NOT_FOUND: pubsub unknown_pubsub is not found
|
||||
|
||||
== APP == Reason: DAPR_PUBSUB_NOT_FOUND
|
||||
|
||||
== APP == Error payload size: 116
|
||||
...
|
||||
|
||||
```
|
||||
|
|
|
|||
|
|
@ -52,10 +52,10 @@ public final class TestUtils {
|
|||
DaprException daprException = Assertions.assertThrows(DaprException.class, executable);
|
||||
Assertions.assertEquals(expectedErrorCode, daprException.getErrorCode());
|
||||
Assertions.assertEquals(expectedErrorMessage, daprException.getMessage());
|
||||
Assertions.assertNotNull(daprException.getStatusDetails());
|
||||
Assertions.assertNotNull(daprException.getErrorDetails());
|
||||
Assertions.assertEquals(
|
||||
expectedReason,
|
||||
daprException.getStatusDetails().get(
|
||||
daprException.getErrorDetails().get(
|
||||
DaprErrorDetails.ErrorDetailType.ERROR_INFO,
|
||||
"reason",
|
||||
TypeRef.STRING
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ public class MethodInvokeIT extends BaseIT {
|
|||
assertEquals("UNKNOWN", exception.getErrorCode());
|
||||
assertNotNull(exception.getMessage());
|
||||
assertTrue(exception.getMessage().contains("Internal Server Error"));
|
||||
assertTrue(new String(exception.getPayload()).contains("Internal Server Error"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||
import io.dapr.client.domain.Metadata;
|
||||
import io.dapr.config.Properties;
|
||||
import io.dapr.exceptions.DaprError;
|
||||
import io.dapr.exceptions.DaprErrorDetails;
|
||||
import io.dapr.exceptions.DaprException;
|
||||
import io.dapr.utils.Version;
|
||||
import okhttp3.Call;
|
||||
|
|
@ -350,7 +349,7 @@ public class DaprHttp implements AutoCloseable {
|
|||
try {
|
||||
return DAPR_ERROR_DETAILS_OBJECT_MAPPER.readValue(json, DaprError.class);
|
||||
} catch (IOException e) {
|
||||
throw new DaprException("UNKNOWN", new String(json, StandardCharsets.UTF_8));
|
||||
throw new DaprException("UNKNOWN", new String(json, StandardCharsets.UTF_8), json);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -383,18 +382,19 @@ public class DaprHttp implements AutoCloseable {
|
|||
public void onResponse(@NotNull Call call, @NotNull okhttp3.Response response) throws IOException {
|
||||
if (!response.isSuccessful()) {
|
||||
try {
|
||||
DaprError error = parseDaprError(getBodyBytesOrEmptyArray(response));
|
||||
byte[] payload = getBodyBytesOrEmptyArray(response);
|
||||
DaprError error = parseDaprError(payload);
|
||||
if ((error != null) && (error.getErrorCode() != null)) {
|
||||
if (error.getMessage() != null) {
|
||||
future.completeExceptionally(new DaprException(error));
|
||||
future.completeExceptionally(new DaprException(error, payload));
|
||||
} else {
|
||||
future.completeExceptionally(
|
||||
new DaprException(error.getErrorCode(), "HTTP status code: " + response.code()));
|
||||
new DaprException(error.getErrorCode(), "HTTP status code: " + response.code(), payload));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
future.completeExceptionally(new DaprException("UNKNOWN", "HTTP status code: " + response.code()));
|
||||
future.completeExceptionally(new DaprException("UNKNOWN", "HTTP status code: " + response.code(), payload));
|
||||
return;
|
||||
} catch (DaprException e) {
|
||||
future.completeExceptionally(e);
|
||||
|
|
|
|||
|
|
@ -37,13 +37,19 @@ public class DaprException extends RuntimeException {
|
|||
*/
|
||||
private DaprErrorDetails errorDetails;
|
||||
|
||||
/**
|
||||
* Optional payload, if the exception came from a response body.
|
||||
*/
|
||||
private byte[] payload;
|
||||
|
||||
/**
|
||||
* New exception from a server-side generated error code and message.
|
||||
*
|
||||
* @param daprError Server-side error.
|
||||
* @param payload Payload containing the error.
|
||||
*/
|
||||
public DaprException(DaprError daprError) {
|
||||
this(daprError.getErrorCode(), daprError.getMessage(), daprError.getDetails());
|
||||
public DaprException(DaprError daprError, byte[] payload) {
|
||||
this(daprError.getErrorCode(), daprError.getMessage(), daprError.getDetails(), payload);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -71,9 +77,10 @@ public class DaprException extends RuntimeException {
|
|||
*
|
||||
* @param errorCode Client-side error code.
|
||||
* @param message Client-side error message.
|
||||
* @param payload Error's raw payload.
|
||||
*/
|
||||
public DaprException(String errorCode, String message) {
|
||||
this(errorCode, message, DaprErrorDetails.EMPTY_INSTANCE);
|
||||
public DaprException(String errorCode, String message, byte[] payload) {
|
||||
this(errorCode, message, DaprErrorDetails.EMPTY_INSTANCE, payload);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -82,9 +89,10 @@ public class DaprException extends RuntimeException {
|
|||
* @param errorCode Client-side error code.
|
||||
* @param message Client-side error message.
|
||||
* @param errorDetails Details of the error from runtime.
|
||||
* @param payload Payload containing the error.
|
||||
*/
|
||||
public DaprException(String errorCode, String message, List<Map<String, Object>> errorDetails) {
|
||||
this(errorCode, message, new DaprErrorDetails(errorDetails));
|
||||
public DaprException(String errorCode, String message, List<Map<String, Object>> errorDetails, byte[] payload) {
|
||||
this(errorCode, message, new DaprErrorDetails(errorDetails), payload);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -93,11 +101,13 @@ public class DaprException extends RuntimeException {
|
|||
* @param errorCode Client-side error code.
|
||||
* @param message Client-side error message.
|
||||
* @param errorDetails Details of the error from runtime.
|
||||
* @param payload Payload containing the error.
|
||||
*/
|
||||
public DaprException(String errorCode, String message, DaprErrorDetails errorDetails) {
|
||||
public DaprException(String errorCode, String message, DaprErrorDetails errorDetails, byte[] payload) {
|
||||
super(String.format("%s: %s", errorCode, message));
|
||||
this.errorCode = errorCode;
|
||||
this.errorDetails = errorDetails;
|
||||
this.payload = payload;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -123,11 +133,14 @@ public class DaprException extends RuntimeException {
|
|||
* permitted, and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
* @param errorDetails the status details for the error.
|
||||
* @param payload Raw error payload.
|
||||
*/
|
||||
public DaprException(String errorCode, String message, Throwable cause, DaprErrorDetails errorDetails) {
|
||||
public DaprException(
|
||||
String errorCode, String message, Throwable cause, DaprErrorDetails errorDetails, byte[] payload) {
|
||||
super(String.format("%s: %s", errorCode, emptyIfNull(message)), cause);
|
||||
this.errorCode = errorCode;
|
||||
this.errorDetails = errorDetails == null ? DaprErrorDetails.EMPTY_INSTANCE : errorDetails;
|
||||
this.payload = payload;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -139,10 +152,24 @@ public class DaprException extends RuntimeException {
|
|||
return this.errorCode;
|
||||
}
|
||||
|
||||
public DaprErrorDetails getStatusDetails() {
|
||||
/**
|
||||
* Returns the exception's error details.
|
||||
*
|
||||
* @return Error details.
|
||||
*/
|
||||
public DaprErrorDetails getErrorDetails() {
|
||||
return this.errorDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exception's error payload (optional).
|
||||
*
|
||||
* @return Error's payload.
|
||||
*/
|
||||
public byte[] getPayload() {
|
||||
return this.payload == null ? null : this.payload.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an exception into DaprException (if not already DaprException).
|
||||
*
|
||||
|
|
@ -247,7 +274,9 @@ public class DaprException extends RuntimeException {
|
|||
statusRuntimeException.getStatus().getCode().toString(),
|
||||
statusRuntimeException.getStatus().getDescription(),
|
||||
exception,
|
||||
errorDetails);
|
||||
errorDetails,
|
||||
status.toByteArray());
|
||||
|
||||
}
|
||||
|
||||
e = e.getCause();
|
||||
|
|
|
|||
|
|
@ -388,6 +388,7 @@ public class DaprClientHttpTest {
|
|||
|
||||
assertEquals("UNKNOWN", exception.getErrorCode());
|
||||
assertEquals("UNKNOWN: { \"anything\": 7 }", exception.getMessage());
|
||||
assertEquals("{ \"anything\": 7 }", new String(exception.getPayload()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ public class DaprHttpTest {
|
|||
DaprException daprException = (DaprException)e;
|
||||
assertEquals("ERR_PUBSUB_NOT_FOUND", daprException.getErrorCode());
|
||||
assertEquals("DAPR_PUBSUB_NOT_FOUND",
|
||||
daprException.getStatusDetails()
|
||||
daprException.getErrorDetails()
|
||||
.get(DaprErrorDetails.ErrorDetailType.ERROR_INFO, "reason", TypeRef.STRING));
|
||||
return true;
|
||||
}).verify();
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import org.junit.jupiter.api.function.Executable;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.Map;
|
||||
|
||||
public final class TestUtils {
|
||||
|
||||
|
|
@ -71,7 +70,7 @@ public final class TestUtils {
|
|||
Assertions.assertEquals(expectedType, daprException.getCause().getClass());
|
||||
Assertions.assertEquals(expectedErrorCode, daprException.getErrorCode());
|
||||
Assertions.assertEquals(expectedErrorMessage, daprException.getMessage());
|
||||
Assertions.assertEquals(expectedStatusDetails, daprException.getStatusDetails());
|
||||
Assertions.assertEquals(expectedStatusDetails, daprException.getErrorDetails());
|
||||
}
|
||||
|
||||
public static int findFreePort() throws IOException {
|
||||
|
|
|
|||
Loading…
Reference in New Issue