php复制代码try{
//可能存在异常的代码
...
}catch (Exception e){
e.printStackTrace();
}
typescript复制代码@GetMapping("wrong")
public void wrong(){
try {
//读文件操作
readFile();
} catch (IOException e) {
//原始异常信息丢失
throw new RuntimeException("读取文件发生IO异常了!");
}
}
typescript复制代码@GetMapping("wrong")
public void wrong(){
try {
//读文件操作
readFile();
} catch (IOException e) {
//只保留了异常消息,栈没有记录
log.error("文件读取错误, {}", e.getMessage());
throw new RuntimeException("读取文件发生异常了!");
}
}
typescript复制代码@GetMapping("right1")
public void right1(){
try {
//读文件操作
readFile();
} catch (IOException e) {
log.error("文件读取错误", e);
throw new RuntimeException("读取文件发生IO异常了!");
}
}
或者
typescript复制代码@GetMapping("right2")
public void right2(){
try {
//读文件操作
readFile();
} catch (IOException e) {
throw new RuntimeException("读取文件发生IO异常了", e);
}
}
typescript复制代码@GetMapping("wrong")
public void wrong(){
try {
//读文件操作
readFile();
} catch (IOException e) {
//没有指定任何异常信息
throw new RuntimeException();
}
}
ini复制代码int i=0;
int y=2;
try {
int z=y/i;
} catch (Exception e) {
log.info( "异常信息" ,e);
log.info( "异常信息:" +e);
}
typescript复制代码 @GetMapping( "wrong" )
public void wrong() {
try {
log.info( "try" );
//finally异常会覆盖掉try里面的异常
throw new RuntimeException( "try" );
} finally {
log.info( "finally" );
throw new RuntimeException( "finally" );
}
}
结果
ini复制代码[13:34:42.247] [http-nio-45678-exec-1] [ERROR] [.a.c.c.C.[.[.[/].[dispatcherServlet]:175 ] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: finally] with root cause
java.lang.RuntimeException: finally
至于异常为什么被覆盖,因为一个方法无法出现两个异常。修复方式是,finally 代码块自己负责异常捕获和处理。
php复制代码@GetMapping("right")
public void right() {
try {
log.info("try");
throw new RuntimeException("try");
} finally {
log.info("finally");
try {
throw new RuntimeException("finally");
} catch (Exception ex) {
log.error("finally", ex);
}
}
}
或者可以把 try 中的异常作为主异常抛出,使用 addSuppressed 方法把 finally 中的异常附加到主异常上:
php复制代码@GetMapping("right2")
public void right2() throws Exception {
Exception e = null;
try {
log.info("try");
throw new RuntimeException("try");
} catch (Exception ex) {
e = ex;
} finally {
log.info("finally");
try {
throw new RuntimeException("finally");
} catch (Exception ex) {
if (e!= null) {
e.addSuppressed(ex);
} else {
e = ex;
}
}
}
throw e;
}
结果:
php复制代码java.lang.RuntimeException: try
at org.geekbang.time.commonmistakes.exception.finallyissue.FinallyIssueController.right2(FinallyIssueController.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
Suppressed: java.lang.RuntimeException: finally
at org.geekbang.time.commonmistakes.exception.finallyissue.FinallyIssueController.right2(FinallyIssueController.java:75)
... 54 common frames omitted
java复制代码public class Exceptions {
public static BusinessException ORDEREXISTS = new BusinessException("兑换失败异常!", 3001);
...
}
然后两个地方异常抛出
typescript复制代码@GetMapping("wrong")
public void wrong() {
try {
exceptionOne();
} catch (Exception ex) {
log.error("exception One error", ex);
}
try {
exceptionTwo();
} catch (Exception ex) {
log.error("exception Two error", ex);
}
}
private void exceptionOne() {
//这里有问题
throw Exceptions.ORDEREXISTS;
}
private void exceptionTwo() {
//这里有问题
throw Exceptions.ORDEREXISTS;
}
exceptionTwo抛出的异常很有可能是exceptionOne抛出的异常,正确的是每次new一个新的。
csharp复制代码public class Exceptions {
public static BusinessException exceptionExists(){
return new BusinessException("兑换失败异常!", 3001);
}
}
备注:参照极客时间 朱晔《Java 业务开发常见错误100例》
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。