Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds error payload to DaprException. #1009

Merged
merged 5 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@
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
Expand All @@ -45,10 +40,11 @@ public static void main(String[] args) throws Exception {
} 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");
Expand Down
4 changes: 4 additions & 0 deletions examples/src/main/java/io/dapr/examples/exception/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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
-->
Expand All @@ -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
...

```
Expand Down
4 changes: 2 additions & 2 deletions sdk-tests/src/test/java/io/dapr/it/TestUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ public static <T extends Throwable> void assertThrowsDaprExceptionWithReason(
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ public void testInvokeException() throws Exception {
assertEquals("UNKNOWN", exception.getErrorCode());
assertNotNull(exception.getMessage());
assertTrue(exception.getMessage().contains("Internal Server Error"));
assertTrue(new String(exception.getPayload()).contains("Internal Server Error"));
}
}
}
12 changes: 6 additions & 6 deletions sdk/src/main/java/io/dapr/client/DaprHttp.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
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;
Expand Down Expand Up @@ -350,7 +349,7 @@ private static DaprError parseDaprError(byte[] json) {
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);
}
}

Expand Down Expand Up @@ -383,18 +382,19 @@ public void onFailure(Call call, IOException e) {
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);
Expand Down
49 changes: 39 additions & 10 deletions sdk/src/main/java/io/dapr/exceptions/DaprException.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -71,9 +77,10 @@ public DaprException(Throwable exception) {
*
* @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);
}

/**
Expand All @@ -82,9 +89,10 @@ public DaprException(String errorCode, String message) {
* @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);
}

/**
Expand All @@ -93,11 +101,13 @@ public DaprException(String errorCode, String message, List<Map<String, Object>>
* @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;
}

/**
Expand All @@ -123,11 +133,14 @@ public DaprException(String errorCode, String message, Throwable cause) {
* 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;
}

/**
Expand All @@ -139,10 +152,24 @@ public String getErrorCode() {
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).
*
Expand Down Expand Up @@ -247,7 +274,9 @@ public static RuntimeException propagate(Throwable exception) {
statusRuntimeException.getStatus().getCode().toString(),
statusRuntimeException.getStatus().getDescription(),
exception,
errorDetails);
errorDetails,
status.toByteArray());

}

e = e.getCause();
Expand Down
1 change: 1 addition & 0 deletions sdk/src/test/java/io/dapr/client/DaprClientHttpTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ public void invokeServiceDaprErrorUnknownJSON() {

assertEquals("UNKNOWN", exception.getErrorCode());
assertEquals("UNKNOWN: { \"anything\": 7 }", exception.getMessage());
assertEquals("{ \"anything\": 7 }", new String(exception.getPayload()));
}

@Test
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/test/java/io/dapr/client/DaprHttpTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ public void validateExceptionParsing() {
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();
Expand Down
3 changes: 1 addition & 2 deletions sdk/src/test/java/io/dapr/utils/TestUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import java.io.IOException;
import java.net.ServerSocket;
import java.util.Map;

public final class TestUtils {

Expand Down Expand Up @@ -71,7 +70,7 @@ public static <T extends Throwable> void assertThrowsDaprException(
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 {
Expand Down