The intent is that the application can define/use whatever keys it
wants - though C++/Python don't expose that fully, which is another
shortcoming that should be addressed. We should also perhaps consider
standardizing/exposing a way to set that extra_info header in
Python/C++ from Java and vice versa.

David

On 8/19/20, Patrick Woody <patrick.woo...@gmail.com> wrote:
> Cool yeah, I had noticed that and it is definitely something that should be
> fixed.
>
> I think that is only one part of it though, right? We'd still need to toss
> the keys in the metadata for it to be picked up on the C++ side. I'm not
> sure if that set of keys is documented or even appropriate to rely on
> cross-language though.
>
>
> On Wed, Aug 19, 2020 at 2:09 PM David Li <li.david...@gmail.com> wrote:
>
>> Ah - I see. I filed https://issues.apache.org/jira/browse/ARROW-9802.
>>
>> At a quick glance, I think what's wrong is StatusUtils.toGrpcStatus
>> doesn't copy the metadata from the CallStatus into the gRPC status it
>> constructs. This should be an easy enough fix if you'd like to look at
>> it. (Adding an integration test to go with it would be ideal.)
>>
>> Constructing a gRPC status directly is also fine. In the future we may
>> explore non-gRPC transports, so it may not be as portable, but that's
>> probably a ways off.
>>
>> Thanks,
>> David
>>
>> On 8/19/20, Patrick Woody <patrick.woo...@gmail.com> wrote:
>> > Hey David,
>> >
>> > Appreciate the quick response!
>> >
>> > 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<byte[]> arrowStatusDetail =
>> >     Metadata.Key.of("x-arrow-status-detail-bin",
>> > Metadata.BINARY_BYTE_MARSHALLER);
>> > private static Metadata.Key<byte[]> grpcStatusDetail =
>> >     Metadata.Key.of("grpc-status-details-bin",
>> > Metadata.BINARY_BYTE_MARSHALLER);
>> > private static Metadata.Key<String> statusCode =
>> >     Metadata.Key.of("x-arrow-status",
>> > Metadata.ASCII_STRING_MARSHALLER);
>> > private static Metadata.Key<byte[]> 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);
>> >
>> > 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.
>> >
>> > Best,
>> > Pat
>> >
>> >
>> >
>> > On Wed, Aug 19, 2020 at 12:59 PM David Li <li.david...@gmail.com>
>> > wrote:
>> >
>> >> Hey Patrick,
>> >>
>> >> How are you sending the error to the client from the server side? You
>> >> should be calling `listener.error` or `listener.onError` with a
>> >> `FlightRuntimeException` (which you can get via
>> >> CallStatus.<STATUS_NAME>.withDescription(...).toRuntimeException);
>> >> this will get the status code and message to the client.
>> >>
>> >> The error metadata is if you need to send additional structured data
>> >> as part of the error.
>> >>
>> >> Best,
>> >> David
>> >>
>> >> On 8/19/20, Patrick Woody <patrick.woo...@gmail.com> wrote:
>> >> > Hey all,
>> >> >
>> >> > I'm working on a project that has a Java arrow flight server and has
>> >> > a
>> >> > pyarrow client, both version 1.0.0. I've been trying to get richer
>> >> > errors
>> >> > back to the python client instead of the generic "grpc error ...".
>> >> >
>> >> > I see that the spec explicitly doesn't try to define metadata:
>> >> > https://arrow.apache.org/docs/format/Flight.html#error-handling, but
>> I
>> >> > think it would certainly be useful to have them work together. It
>> >> > appears
>> >> > that the Java implementation doesn't seem to send the
>> >> > ErrorFlightMetadata
>> >> > and the C++ code has its own way of best effort extracting of
>> >> > additional
>> >> > metadata from the response
>> >> >
>> >>
>> https://github.com/apache/arrow/blob/master/cpp/src/arrow/flight/internal.cc#L86
>> >> >
>> >> > As of now, I'm just manually making the grpc metadata/exception so
>> that
>> >> > pyarrow understands it but I'm curious if this is a problem others
>> have
>> >> run
>> >> > into / if I'm doing something silly. Similarly, I am wondering if
>> >> > this
>> >> > is
>> >> > something that requires cross-language definition - I'm a little
>> >> > unclear
>> >> on
>> >> > the divide between what is considered a part of the Flight spec v.s.
>> >> > implementation specific. Happy to help if there is some follow up
>> >> > work
>> >> > here.
>> >> >
>> >> > Thanks!
>> >> > Pat
>> >> >
>> >>
>> >
>>
>

Reply via email to