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

tri怎么实现异常重放呢 #9310

Closed
feng996 opened this issue Nov 23, 2021 · 4 comments
Closed

tri怎么实现异常重放呢 #9310

feng996 opened this issue Nov 23, 2021 · 4 comments

Comments

@feng996
Copy link

feng996 commented Nov 23, 2021

dubbo.version=3.0.4
dubbo.protocol=tri

provider throw的所有异常在consumer端都会被包装为RpcException。
怎么能在consumer端重放provider发生的异常呢

这里是UnaryClientStream$UnaryClientTransportObserver#getThrowable

private Throwable getThrowable(Metadata metadata) {
            if (null == metadata) {
                return null;
            }
            // second get status detail
            if (!metadata.contains(TripleHeaderEnum.STATUS_DETAIL_KEY.getHeader())) {
                return null;
            }
            final CharSequence raw = metadata.get(TripleHeaderEnum.STATUS_DETAIL_KEY.getHeader());
            byte[] statusDetailBin = TripleUtil.decodeASCIIByte(raw);
            ClassLoader tccl = Thread.currentThread().getContextClassLoader();
            try {
                final Status statusDetail = TripleUtil.unpack(statusDetailBin, Status.class);
                List<Any> detailList = statusDetail.getDetailsList();
                Map<Class<?>, Object> classObjectMap = TripleUtil.tranFromStatusDetails(detailList);

                // get common exception from DebugInfo
                DebugInfo debugInfo = (DebugInfo) classObjectMap.get(DebugInfo.class);
                if (debugInfo == null) {
                    return new RpcException(statusDetail.getCode(),
                        statusDetail.getMessage());
                }
                String msg = ExceptionUtils.getStackFrameString(debugInfo.getStackEntriesList());
                return new RpcException(statusDetail.getCode(), msg);
            } finally {
                ClassLoadUtil.switchContextLoader(tccl);
            }
        }

consumer处理异常时都会被包装为RpcException

@EarthChen
Copy link
Member

由于 tri 协议使用的是 pb 作为序列化,对异常的支持较差,并且异常是通过 http2的 header 部分进行传输的,这部分是有大小限制的。所以对于异常没有进行序列化传输。
所以在 tri 协议中,无法传递完整异常。
大部分的传递异常的需求都是服务端抛业务异常,客户端进行相应的处理。可以参考#8363

@feng996 feng996 closed this as completed Nov 25, 2021
@feng996
Copy link
Author

feng996 commented Nov 25, 2021

参考 #8369 实现
多添加了一个异常全限定类名,consumer端可实现重放。
message带中文放到attachments里,会有编码问题,可以先在provider转成latin1在consumer端转回去

@feng996 feng996 reopened this Dec 7, 2021
@feng996
Copy link
Author

feng996 commented Dec 7, 2021

参考 #8369 的实现,确实能在A -> B B端抛出异常A捕获,但是在A -> B -> C C端抛出的异常,无法传递到A,在B只会触发failfast超时的onError。 @EarthChen

@feng996
Copy link
Author

feng996 commented Dec 7, 2021

重写onResponse时,得把异常的stacktrace给设置为null。不然,只会被MonitorFilter的超时异常提前抛出,就调用onError了

if (className.startsWith("java.") || className.startsWith("javax.")) {
exception.setStackTrace(null);
return;
}

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

No branches or pull requests

2 participants