抛出的异常在上层catch到,但是e.getMessage()为NULL,为什么会这样?

1.在一个代码里catch到Exception,throw new Exception(e.getMessage());
在上级代码里catch到抛出的Exception,想得到错误的信息,结果发现e.getMessage()却为null
debug的时候发现抛出的e里面有个undeclaredThrowable,这个才是抛出的异常。不懂这到底是什么原理。

2.代码如下

server层代码:

public A methodA(){
    try{
        int a = 10/0;//这里会抛出ArithmeticException
    } catch(Exception e){
        throw new Exception(e.getMessage());
    }
    return null;
}

control层代码:

public methodB(){
    try{
        A a = sercer.methodA();
    } catch(Exception e){
        System.out.println(e.getMessage());//这里为NULL
    }
}

这个是debug看到的信息,不是Exception,也不是ArithmeticException,而是UndeclaredThrowableException。在undeclaredThrowable里面有着底层抛出的信息。
clipboard.png

3.这是什么原因造成。不是特别能理解

阅读 23.6k
3 个回答

如果你要输出异常信息:

// Exception ex;
ex.printStackTrace();

如果是得到异常信息:

// Exception e;
ByteArrayOutputStream out = new ByteArrayOutputStream();
PrintStream pout = new PrintStream(out);
e.printStackTrace(pout);
String ret = new String(out.toByteArray());
pout.close();
try {
    out.close();
} catch (Exception ex) {
    ex.printStackTrace();
}

// 控制台打印整个错误栈  ret
System.out.println(ret);

关于异常相关的东西其实也不少,有兴趣可以好好看看API及解读一下源码

  1. 你methodA 抛出的异常是 ArithmeticException
    ArithmeticException的 message 本来就是 null

于是下面的代码相当于 throw new Exception(null);

2 你使用的应该是Spring或者之类的框架
service 对象其实已经是框架托管的代理类。
于是你的异常被包装成了 UndeclaredThrowableException
你可以调用一下 Exception的getCause方法找到原始的异常

3 打印异常堆栈 可以用 e.printStackTrace();

可能是框架的AOP机制造成。controller获取的是service的代理实例,service的exception经过代理后转换成了UndeclaredThrowableException。看stack信息一层一层进源码分析,试试。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题