Skip to content

Ability to propagate cause when using StatusProto.toStatusException #10900

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

Closed
jasnross opened this issue Feb 7, 2024 · 6 comments · Fixed by #11083
Closed

Ability to propagate cause when using StatusProto.toStatusException #10900

jasnross opened this issue Feb 7, 2024 · 6 comments · Fixed by #11083

Comments

@jasnross
Copy link

jasnross commented Feb 7, 2024

Is your feature request related to a problem?

When converting a com.google.rpc.Status to an io.grpc.StatusException I can't find a way to propagate a cause with the resulting StatusException.

Currently StatusProto.toStatusException is defined as:

  public static StatusException toStatusException(com.google.rpc.Status statusProto) {
    return toStatus(statusProto).asException(toMetadata(statusProto));
  }

However, using this method there doesn't seem to be any way of providing a cause.

Describe the solution you'd like

My ideal would be to make StatusProto.toStatus public, which would allow creating the status and calling asException something callers could do themselves. This would also be helpful in scenarios where callers require a Status instead of a StatusException.

  private static Status toStatus(com.google.rpc.Status statusProto) {
    Status status = Status.fromCodeValue(statusProto.getCode());
    checkArgument(status.getCode().value() == statusProto.getCode(), "invalid status code");
    return status.withDescription(statusProto.getMessage());
  }

Describe alternatives you've considered

It feels a little clunky, but I'd be open to having an extra parameter on toStatusException for the cause, or another solution depending on the preferences of grpc-java maintainers.

I've also tried calling initCause on the resulting StatusException, but that isn't possible because the cause is set to null in the asException code, so initCause throws an IllegalArgumentException.

Additional context

@jasnross jasnross changed the title Difficult to propagate cause when using StatusProto.toStatusException Cannot propagate cause when using StatusProto.toStatusException Feb 7, 2024
@jasnross jasnross changed the title Cannot propagate cause when using StatusProto.toStatusException Ability to propagate cause when using StatusProto.toStatusException Feb 7, 2024
@ejona86
Copy link
Member

ejona86 commented Feb 13, 2024

Cause isn't sent over the wire, so the status isn't being used for an RPC?

StatusProto's API was designed to make sure io.grpc.Status and com.google.rpc.Status agree. It'd be very bad for one to say OK and the other to be PERMISSION_DENIED, for example. But it sounds like you are using com.google.rpc.Status within your process for error information. Can you explain more about how your app code is organized to use this?

@sergiitk sergiitk added the Waiting on reporter there was a request for more information without a response or answer or advice has been provided label Feb 13, 2024
@jasnross
Copy link
Author

jasnross commented Feb 19, 2024

Thanks for the reply!

The way our application is designed is that exceptions in our gRPC services are expected to ultimately return StatusException, and eventually that StatusException is translated into a response. Just before that happens typically we log the exception (if it is one of the types we are interested in logging - for example, INTERNAL), and would like to have the cause there for logging purposes.

We recently incorporated com.google.rpc.Status into our responses in order to provide a richer payload of response data (invalid fields with BadRequest, etc.) but prior to that we were just using Status#withCause:

io.grpc.Status.INTERNAL.withDescription("Message to API caller.").withCause(someException).asException()

When we logged this we would get the stack trace from the cause, which can be useful for debugging.

For now we are working around it by building the io.grpc.Status from com.google.rpc.Status ourselves and calling withCause on it, but ideally I was thinking there could be a way to add the exception while still benefiting from the StatusProto conversion code that grpc-java provides.

@ejona86
Copy link
Member

ejona86 commented Feb 20, 2024

I see. Local logging. That's quite fair.

Worst-case adding a overload that also receives a Throwable could work. I don't think we'd have a Metadata-less overload, but maybe Metadata would be permitted to be null instead of required. But we have a few overloads, so it'd probably be good to look around to see if there's something more natural (I'm not seeing anything immediately, but I've only spent 15 seconds looking at it).

@ejona86 ejona86 removed the Waiting on reporter there was a request for more information without a response or answer or advice has been provided label Feb 20, 2024
@temawi
Copy link
Contributor

temawi commented Mar 8, 2024

@ejona86 What is your thinking - is this an enhancement we should take up?

@ejona86
Copy link
Member

ejona86 commented Mar 8, 2024

I do think we should do something here. There's just the question of the API.

@ejona86
Copy link
Member

ejona86 commented Mar 20, 2024

I think the easiest/best think right now is just to add another overload (like I said in #10900 (comment)). I don't think there's going to be any cleaner API unless we introduce a builder.

Feel free to send a PR.

@ejona86 ejona86 added this to the Unscheduled milestone Mar 20, 2024
@larry-safran larry-safran modified the milestones: Unscheduled, Next Mar 26, 2024
@ejona86 ejona86 modified the milestones: Next, 1.64 Apr 25, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants