dromara / myth

Reliable messages resolve distributed transactions
https://dromara.org
Apache License 2.0
1.49k stars 603 forks source link

解决MythMqReceiveServiceImpl的processMessage通过异步调用业务方法后,无法获取业务层抛出的异常详情 #104

Closed zhaoshengwolf closed 2 years ago

zhaoshengwolf commented 2 years ago

详情如下: 当spring使用cglib为AccountServiceImpl生成代理类时,会对AccountServiceImpl抛出的异常进行一层包装(throw new InvocationTargetException(var4);),然后再向外抛出

所以在MykitMqReceiveServiceImpl的processMessage方法里的catch中无法直接通过e.getMessage()获取到真实的AccountServiceImpl中抛出的异常,需要添加一层判断

/**

通过cglib生成的代码理如下(关键就是在 catch后会 throw new InvocationTargetException(var4);对业务抛出的异常进行了一些包装) public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException { try { AccountServiceImpl var10000 = (AccountServiceImpl)var2; int var10001 = var1;

    try {
        switch(var10001) {
        case 0:
            return new Boolean(var10000.payment((AccountDto)var3[0]));
        case 1:
            return var10000.findByUserId((String)var3[0]);
        case 2:
            return new Boolean(var10000.equals(var3[0]));
        case 3:
            return var10000.toString();
        case 4:
            return new Integer(var10000.hashCode());
        }
    } catch (Throwable var4) {
        throw new InvocationTargetException(var4);
    }

    throw new IllegalArgumentException("Cannot find matching method/constructor");
} catch (Error | InvocationTargetException | RuntimeException var5) {
    throw var5;
} catch (Throwable var6) {
    throw new UndeclaredThrowableException(var6);
}

}