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

[Bug] How to get attachment data in the consumer ,attachment data set from provider cusome exception filter? #14416

Open
4 tasks done
GongLe opened this issue Jul 11, 2024 · 8 comments
Labels
component/need-triage Need maintainers to triage type/need-triage Need maintainers to triage

Comments

@GongLe
Copy link

GongLe commented Jul 11, 2024

Pre-check

  • I am sure that all the content I provide is in English.

Search before asking

  • I had searched in the issues and found no similar issues.

Apache Dubbo Component

Java SDK (apache/dubbo)

Dubbo Version

3.2.14

Steps to reproduce this issue

How to get attachment data in the consumer ,attachment data set from provider cusome exception filter ?
DubboProviderExceptionFilter:
RpcContextAttachment serverContext = RpcContext.getServerContext();
serverContext.setObjectAttachment(ATTA_NAME_EXCEPTION_CODE, br.getCode());
DubboConsumerExceptionFilter:
RpcContext.getServerContext().getObjectAttachments() ,RpcContext.getContext().getAttachments();
Neither method can be obtained

What you expected to happen

DubboProviderExceptionFilter set attachment data , DubboConsumerExceptionFilter get server attachment data ,used to customize exceptions extra data

Anything else

source code:

@Activate(group = CommonConstants.PROVIDER )
public class DubboProviderExceptionFilter implements Filter, Filter.Listener {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    public static String ATTA_NAME_EXCEPTION_CODE = "__code";
    public static String ATTA_NAME_EXCEPTION_DETAIL_MSG = "__detailMsg";
    public static String ATTA_NAME_EXCEPTION_DETAIL_DATA = "__data";

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        return invoker.invoke(invocation);
    }

    @Override
    public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
        if (appResponse.hasException() && GenericService.class != invoker.getInterface()) {
            try {
                Throwable exception = appResponse.getException();

                String className = exception.getClass().getName();
                //如果是我们系统自定义异常直接返回
                if ( ClassUtil2.isAssignable(ServiceException.class, exception.getClass())) {
                    //服务提供方写入回传参数
                    ServiceException br = (ServiceException) exception;
                    invocation.setObjectAttachment(ATTA_NAME_EXCEPTION_CODE, br.getCode());
                    invocation.setObjectAttachment(ATTA_NAME_EXCEPTION_DETAIL_MSG, br.getDetailMsg());
                    invocation.setObjectAttachment(ATTA_NAME_EXCEPTION_DETAIL_DATA, br.getExtraData());

                    RpcContextAttachment serverContext = RpcContext.getServerContext();
                    serverContext.setObjectAttachment(ATTA_NAME_EXCEPTION_CODE, br.getCode());
                    serverContext.setObjectAttachment(ATTA_NAME_EXCEPTION_DETAIL_MSG, br.getDetailMsg());
                    serverContext.setObjectAttachment(ATTA_NAME_EXCEPTION_DETAIL_DATA, br.getExtraData());

                    return;
                }

@Activate(group = CommonConstants.CONSUMER )
public class DubboConsumerExceptionFilter implements Filter, Filter.Listener {

   @Override
   public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
       Throwable exec = appResponse.getException();
       if (exec != null && ServiceException.class.isAssignableFrom(exec.getClass())) {
           Map<String, String> attachments = invocation.getAttachments();


           if (attachments.containsKey(ATTA_NAME_EXCEPTION_CODE)) {
               ReflectionUtil.setFieldValue(exec, "code", attachments.get(ATTA_NAME_EXCEPTION_CODE));
           }

           if (attachments.containsKey(ATTA_NAME_EXCEPTION_DETAIL_MSG)) {
               ReflectionUtil.setFieldValue(exec, "detailMsg", attachments.get(ATTA_NAME_EXCEPTION_DETAIL_MSG));
           }

           if (attachments.containsKey(ATTA_NAME_EXCEPTION_DETAIL_DATA)) {
               ReflectionUtil.setFieldValue(exec, "extraData", attachments.get(ATTA_NAME_EXCEPTION_DETAIL_DATA));
           }


       }
   }

Are you willing to submit a pull request to fix on your own?

  • Yes I am willing to submit a pull request on my own!

Code of Conduct

@GongLe GongLe added component/need-triage Need maintainers to triage type/need-triage Need maintainers to triage labels Jul 11, 2024
@wcy666103
Copy link
Contributor

wcy666103 commented Jul 11, 2024

Reference here: https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/attachment/

It's not a Bug, it's just a logic problem with the built-in Filter in the framework in the higher version of dubbo, you're using it the wrong way.Please reference herer https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/attachment/#%E5%8E%86%E5%8F%B2%E9%81%97%E7%95%99%E9%97%AE%E9%A2%98

@GongLe
Copy link
Author

GongLe commented Jul 11, 2024

Reference here: https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/attachment/

It's not a Bug, it's just a logic problem with the built-in Filter in the framework in the higher version of dubbo, you're using it the wrong way.Please reference herer https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/attachment/#%E5%8E%86%E5%8F%B2%E9%81%97%E7%95%99%E9%97%AE%E9%A2%98


Thanks for your reply!
I don't understand,How to in consumer side filter get provider attachments data , current provider data is available outside the method.
“ServerContext:在 Client 端和 Server 端使用,用于从 Server 端回传 Client 端使用,Server 端写入到 ServerContext 的参数在调用结束后可以在 Client 端的 ServerContext 获取到”

@GongLe
Copy link
Author

GongLe commented Jul 11, 2024

Reference here: https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/attachment/
It's not a Bug, it's just a logic problem with the built-in Filter in the framework in the higher version of dubbo, you're using it the wrong way.Please reference herer https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/attachment/#%E5%8E%86%E5%8F%B2%E9%81%97%E7%95%99%E9%97%AE%E9%A2%98

Thanks for your reply! I don't understand,How to in consumer side filter get provider attachments data , current provider data is available outside the method. “ServerContext:在 Client 端和 Server 端使用,用于从 Server 端回传 Client 端使用,Server 端写入到 ServerContext 的参数在调用结束后可以在 Client 端的 ServerContext 获取到”

After consumer side filter DubboConsumerExceptionFilter#invoke method ,Still get no data!

  @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { 
        Result invoke = invoker.invoke(invocation);
        if(invoke.hasException()) {
           //.....  get provider attachments data 
        }
        return invoke;
    }

@EarthChen
Copy link
Member

It is not recommended to use obj as Attachment. For some protocols, only some basic types may be supported.

@GongLe
Copy link
Author

GongLe commented Jul 11, 2024

Test on consumer filter set attachment data ,use RpcContext.getClientAttachment().setAttachment api can be transfer to provider filter, use api RpcContext.getServerAttachment().getObjectAttachments()

@GongLe
Copy link
Author

GongLe commented Jul 11, 2024

Actually,It's logic bug ! on the default ConsumerContextFilter onResponse method, will be set clientResponseContext attachments , But custom consumer filter onResponse method always execute the default first

org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter#onResponse

3d9479205b0e3ed2c366b6302fa5ba28

@GongLe
Copy link
Author

GongLe commented Jul 11, 2024

another question,dubbo 3.0 how to define filter like this config : <dubbo:service filter="filter1,default,filter2,-token"/>

@wcy666103
Copy link
Contributor

Can you provide a working program?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component/need-triage Need maintainers to triage type/need-triage Need maintainers to triage
Projects
Status: Todo
Development

No branches or pull requests

3 participants