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

Add the dapr runtime returned error details to the Java DaprException #998

Merged
merged 19 commits into from Feb 13, 2024

Conversation

cicoyle
Copy link
Contributor

@cicoyle cicoyle commented Feb 1, 2024

Description

Add the error details from dapr runtime to the java dapr exception, such that users may parse for error details in their code accordingly.

Here is the output from running the PubSub Client code:
image

Issue reference

dapr/docs#3907 (comment)

Checklist

Please make sure you've completed the relevant tasks for this PR, out of the following list:

  • Code compiles correctly
  • Created/updated tests -> added a test for 1 & more than 1 error details
  • Extended the documentation

…Exception

Signed-off-by: Cassandra Coyle <cassie@diagrid.io>
Signed-off-by: Cassandra Coyle <cassie@diagrid.io>
Signed-off-by: Cassandra Coyle <cassie@diagrid.io>
@cicoyle cicoyle marked this pull request as ready for review February 2, 2024 19:24
@cicoyle cicoyle requested review from a team as code owners February 2, 2024 19:24
Signed-off-by: Cassandra Coyle <cassie@diagrid.io>
Signed-off-by: Cassandra Coyle <cassie@diagrid.io>
Signed-off-by: Cassandra Coyle <cassie@diagrid.io>
Signed-off-by: Cassandra Coyle <cassie@diagrid.io>
Signed-off-by: Cassandra Coyle <cassie@diagrid.io>
Signed-off-by: Cassandra Coyle <cassie@diagrid.io>
@msfussell
Copy link
Member

@cicoyle - Are you doing this for v1.13?

} catch (DaprException exception) {
System.out.println("Error code: " + exception.getErrorCode());
System.out.println("Error message: " + exception.getMessage());

try {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is too complex for users. Can we have an opinionated structure that encapsulates this into the DaprException object?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the latest version with the "opinionated" layer I added.

/**
* Object mapper to parse DaprError with or without details.
*/
private static final ObjectMapper DAPR_ERROR_DETAILS_OBJECT_MAPPER = new ObjectMapper();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarifying my change: no need for a custom ObjectMapper. The stock one is enough now.

result.put("@type", generateErrorTypeFqn(message.getClass()));

for (Field field : fields) {
if (field.isSynthetic() || Modifier.isStatic(field.getModifiers())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarifying my change: This avoids the need to check for _ in the name.

continue;
}

String normalizedFieldName = field.getName().replaceAll("_$", "");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the code still contains _, we need to remove it. If the library decided to stop appending the _ to the attribute names, we would not need to change this code.

}

public enum ErrorDetailType {
ERROR_INFO,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarifying my change: Purposely mapping to our internal types to avoid exposing types from the gRPC library to the app.

return Collections.unmodifiableMap(result);
}

private static <T extends com.google.protobuf.Message> String generateErrorTypeFqn(Class<T> clazz) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarifying my change: just a small refactoring to allow this logic to be reused.

private static final Map<Class<? extends Message>, ErrorDetailType> SUPPORTED_ERROR_TYPES =
Collections.unmodifiableMap(new HashMap<>() {
{
put(com.google.rpc.ErrorInfo.class, ErrorDetailType.ERROR_INFO);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarifying my change: avoids exposing 3rd-party library types to the app.

}
});

private static final Map<String, Class<? extends Message>> ERROR_TYPES_FQN_REVERSE_LOOKUP =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarifying my change: handy to map a string to a class when parsing JSON error response in HTTP API.

try {
client.getState("Unknown state store", "myKey", String.class).block();
client.publishEvent("unknown_pubsub", "mytopic", "mydata").block();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarifying my change: keeping this example simple.

exception.printStackTrace();
System.out.println("Dapr exception's error code: " + exception.getErrorCode());
System.out.println("Dapr exception's message: " + exception.getMessage());
System.out.println("Dapr exception's reason: " + exception.getStatusDetails().get(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarifying my change: this is the opinionated layer in the SDK and determines how users can retrieve error details. We don't enumerate all the attributes on purpose. We can decide to change this later but I think this is a good first design to give a semi-structured way to fetch error details.

Signed-off-by: Artur Souza <asouza.pro@gmail.com>
Signed-off-by: Artur Souza <asouza.pro@gmail.com>
Signed-off-by: Artur Souza <asouza.pro@gmail.com>
@artursouza artursouza dismissed their stale review February 13, 2024 02:07

I redesigned to add an opinionated layer.

Signed-off-by: Artur Souza <asouza.pro@gmail.com>
Signed-off-by: Artur Souza <asouza.pro@gmail.com>
Copy link
Contributor Author

@cicoyle cicoyle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes LGTM Thx! @artursouza

Signed-off-by: Artur Souza <asouza.pro@gmail.com>
Copy link

codecov bot commented Feb 13, 2024

Codecov Report

Attention: 20 lines in your changes are missing coverage. Please review.

Comparison is base (cd81ee8) 77.42% compared to head (1cf7325) 77.56%.

Files Patch % Lines
...main/java/io/dapr/exceptions/DaprErrorDetails.java 79.78% 10 Missing and 9 partials ⚠️
...rc/main/java/io/dapr/exceptions/DaprException.java 92.30% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master     #998      +/-   ##
============================================
+ Coverage     77.42%   77.56%   +0.13%     
- Complexity     1539     1567      +28     
============================================
  Files           143      144       +1     
  Lines          4642     4751     +109     
  Branches        541      554      +13     
============================================
+ Hits           3594     3685      +91     
- Misses          771      781      +10     
- Partials        277      285       +8     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@artursouza artursouza merged commit a3cc138 into dapr:master Feb 13, 2024
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants