Dubbo 统一业务异常处理

995 阅读1分钟

基于Filter的实现方案

package org.jeckxu.magical.core.dubbo.filter;

import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.service.GenericService;
import org.jeckxu.magical.core.basic.exception.BusinessException;
import org.jeckxu.magical.core.basic.exception.ServiceException;
import org.jeckxu.magical.core.dubbo.exception.RpcTraceException;
import org.jeckxu.magical.core.tool.api.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


@Activate(group = CommonConstants.PROVIDER, order = 2)
public class MagicalDubboRpcExceptionFilter implements Filter {

    private static final Logger LOGGER = LoggerFactory.getLogger(MagicalDubboRpcExceptionFilter.class);

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        Result appResponse = invoker.invoke(invocation);
        if (appResponse.hasException() && GenericService.class != invoker.getInterface()) {
            try {
                Throwable e = appResponse.getException();
                LOGGER.error(" [MAGICAL-DUBBO] Fail to MagicalDubboRpcExceptionFilter when called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
                if (e instanceof BusinessException) {
                    BusinessException businessException = (BusinessException) e;
                    return AsyncRpcResult.newDefaultAsyncResult(R.fail(businessException.getResultCode().getCode(), businessException.getMessage()), invocation);
                }
                if (e instanceof ServiceException) {
                    ServiceException serviceException = (ServiceException) e;
                    return AsyncRpcResult.newDefaultAsyncResult(R.fail(serviceException.getResultCode().getCode(), serviceException.getMessage()), invocation);
                }
                if (e instanceof RpcTraceException) {
                    RpcTraceException rpcTraceException = (RpcTraceException) e;
                    return AsyncRpcResult.newDefaultAsyncResult(R.fail(rpcTraceException.getCode(), rpcTraceException.getMessage()), invocation);
                }
            } catch (Throwable e) {
                LOGGER.error(" [MAGICAL-DUBBO] Fail to MagicalDubboRpcExceptionFilter when called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
                return AsyncRpcResult.newDefaultAsyncResult(R.fail(65510, "远程服务调用发生异常"), invocation);
            }
        }
        return appResponse;
    }
}

org.apache.dubbo.rpc.Filter

magicalDubboRpcExceptionFilter=org.jeckxu.magical.core.dubbo.filter.MagicalDubboRpcExceptionFilter

优点:易于维护,便于扩展。

缺点:需要定义统一的业务异常及响应模型。