首页 > 解决方案 > 如何将 Java 异常从箭头飞行服务器传递到客户端?(都使用 Java 库)

问题描述

在接受数据流的acceptPut调用中,我想在箭头飞行服务器端抛出一个异常,该异常应该可供箭头飞行客户端使用,以便客户端可以为客户端的消费者重新抛出它以获得实际的异常。请建议是否有任何标准方法将异常详细信息从箭头飞行服务器传递给客户端?

我试图做的是使用以下代码:如果“ex”是我的自定义异常,那么:

    String customException = objMapper.writeValueAsString(ex);
    ErrorFlightMetadata metadata = new ErrorFlightMetadata();
    metadata.insert("value", customException);
    ackStream.onError(new CallStatus(FlightStatusCode.INTERNAL, ex,
        "CustomException", metadata).toRuntimeException());

但是在箭头飞行客户端,当我运行时:

stream.getResult();

它会抛出 FlightRuntimeException 异常,其中包含我在服务器端设置的正确状态代码和描述,但 ErrorFlightMetadata 对象不存在。

如果 ErrorFlightMetadata 没有从服务器传递到客户端,那么从服务器向客户端发送异常详细信息的替代选项是什么。

标签: apache-arrow

解决方案


在这方面,Arrow Flight 反映了 gRPC Java。虽然 CallStatus 允许您附加异常,但这不会镜像到客户端以避免将有关服务器的详细信息泄露给客户端。

最简单的方法是将异常字符串化并将其包含在错误消息中。只要回溯不太长(几千字节),就可以正常工作。(gRPC,底层传输,默认限制元数据的大小,元数据用于携带错误信息。)

您还可以将自定义键值元数据附加到错误中。

目前(Arrow 4.0.0),这还没有完全实现:参见ARROW-12842。(这在 5.0.0 中是固定的。)所以现在,你必须直接使用 gRPC 的 StatusRuntimeException,例如看这个测试用例:TestErrorMetadata.java

将来,您还可以将元数据附加到 Flight 错误对象: https ://arrow.apache.org/docs/java/reference/org/apache/arrow/flight/CallStatus.html#withMetadata -org.apache.arrow.flight.ErrorFlightMetadata-

在任何一种情况下,请注意客户端默认情况下可能会或可能不会显示此信息。如果您想以编程方式在客户端获取回溯并对其进行处理,这将更加有用。


推荐阅读