apache / apache/arrow-java

[FlightRPC][Java] CallStatus.metadata should get copied into the gRPC StatusRuntimeException

Open
#325 0 comments 0 reactions 0 assignees View on GitHub
Type: bug
Dominant language
Java
Stars
94
Forks
152
Avg merge
3d 16h
Merged PRs (30d)
11

Description

Reported on the mailing list.
```

I had been doing it that way, but I found that If I was sending something
along the lines of:

ErrorFlightMetadata errorFlightMetadata = new ErrorFlightMetadata();
errorFlightMetadata.insert("my_custom_key", "hello");
listener.error(CallStatus.INTERNAL
.withDescription("Testing description")
.withCause(new RuntimeException("My cause"))
.withMetadata(errorFlightMetadata)
.toRuntimeException());

I would only receive the description back by the time it was throwing a
Python error:

FlightInternalError: gRPC returned internal error, with message:
Testing description. Client context: IOError: Server never sent a data
message. Detail: Internal. gRPC client debug context:
{"created":"@1597858462.086707300","description":"Error received from
peer ipv6:[::1]:12233","file":"src/core/lib/surface/call.cc","file_line":1056,"grpc_message":"Testing
description","grpc_status":13}

(catching the exception and checking FlightInternalError.extra_info returns
nothing as well)

However if I manually create a grpc status exception like so:

private static Metadata.Key arrowStatusDetail =
Metadata.Key.of("x-arrow-status-detail-bin",
Metadata.BINARY_BYTE_MARSHALLER);
private static Metadata.Key grpcStatusDetail =
Metadata.Key.of("grpc-status-details-bin", Metadata.BINARY_BYTE_MARSHALLER);
private static Metadata.Key statusCode =
Metadata.Key.of("x-arrow-status", Metadata.ASCII_STRING_MARSHALLER);
private static Metadata.Key message =
Metadata.Key.of("x-arrow-status-message-bin",
Metadata.BINARY_BYTE_MARSHALLER);

Metadata metadata = new Metadata();
metadata.put(arrowStatusDetail, "my_internal_details".getBytes());
metadata.put(grpcStatusDetail, "this_is_in_extra_info".getBytes());
metadata.put(statusCode, "1");
metadata.put(message, "my_internal_message".getBytes());
return new StatusRuntimeException(Status.INTERNAL, metadata);
StatusUtils.toGrpcStatus doesn't copy the metadata from the CallStatus into the gRPC status it constructs.
Then I receive this back on the Python side:

FlightInternalError: my_internal_message. Detail: my_internal_details.
Client context: IOError: Server never sent a data message. Detail:
Internal. gRPC client debug context:
{"created":"@1597859023.244971700","description":"Error received from
peer ipv6:[::1]:12233","file":"src/core/lib/surface/call.cc","file_line":1056,"grpc_message":"","grpc_status":13}

and FlightInternalError.extra_info contains the bytes for
"this_is_in_extra_info" - I can pretty much put whatever I need in there
to add richer metadata and utilize it on the client.

It feels a bit awkward / maybe incorrect to dive into the C++ code to
hijack those metadata keys just to transport extra metadata from Java ->
C++. If the above approach with CallStatus is incorrect for bringing extra
data to the client then let me know.

```
StatusUtils.toGrpcStatus doesn't copy the metadata from the CallStatus into the gRPC status it constructs; I think that's the issue.

**Reporter**: [David Li](https://issues.apache.org/jira/browse/ARROW-9802) / @lidavidm

**Note**: *This issue was originally created as [ARROW-9802](https://issues.apache.org/jira/browse/ARROW-9802). Please see the [migration documentation](https://github.com/apache/arrow/issues/14542) for further details.*

Contributor guide

Open the contributing guide

Research direction

Start with StatusUtils.toGrpcStatus and compare how it constructs the gRPC StatusRuntimeException with the metadata supplied to CallStatus. Verify the resulting exception preserves that metadata and that the reported client-side details are available; add or run focused tests if the surrounding code provides them.

Written by the indexing model from the issue text.

Assessment

Tech stack
grpc, java
Domain
api
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.