异常处理相关心得

2024-09-04 01:52
文章标签 异常 处理 相关 心得

本文主要是介绍异常处理相关心得,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这段时间发现异常捕获是非常重要的一个机制,之前光埋头写代码了,如今想来,除了代码之外,解决问题的能力也是非常重要的,而如何解决问题,异常的捕获不可或缺

@RestControllerAdvice

@RestControllerAdvice 主要用于全局异常处理,它通常能够捕获由
@Controller、@RestController 标注的类中抛出的异常,并对其进行统一处理,意味着从线程池中抛出来的异常就不能被这个类捕获到了

给出一个简单的代码

@RestControllerAdvice
public class MyExceptionHandler {@ExceptionHandler(Exception.class)public String exceptionHandler(Exception e) {return "统一异常处理:" + e.getMessage();}
}

那么这个类能处理的异常就是在 controller 层面的异常,比如:

    @GetMapping("/initiative")public String test() {Date now = new Date();if (true) {throw new RuntimeException("主动抛出异常");}return "test";}//运行时异常--空指针异常/数组越界异常 等等@GetMapping("/runtime")public String runtime() {String str = null;return str.substring(0);}//受检异常--文件找不到异常 等等@GetMapping("/checked")public String checked() throws Exception {FileInputStream fis = new FileInputStream(new File("111datanew.xlsx"));return "checked";}

要注意,如果你 try catch 住了,就比如:

    //try-catch捕获异常@GetMapping("/trycatch")public String trycatch() {try {String str = null;String substring = str.substring(0);System.out.println("substring = " + substring);} catch (Exception e) {}return "trycatch2 请求成功";}

那么你收到的请求结果是 “trycatch2 请求成功”,而不是异常信息

线程池中的异常

实际上,线程池中的异常是比较难处理的一种异常,我们请求接口,然后接口中把一部分任务交给线程池,这通常是为了加快接口相应速度。一种是调用这个接口为的是开启一个任务,那么此时接口只需要封装一个任务交给线程池,然后直接返回 success 即可,另外一种是调整代码执行顺序,利用线程池,将一部分资源先准备好,等到后续用的时候可以更快的获取到。说白了就是,一种需要拿到返回值之后继续执行代码,最后返回success,一种不需要返回值,直接 success。

首先有一个线程池

@Configuration
public class ThreadPoolConfig {@Bean  //创建一个线程池public ThreadPoolExecutor myThreadPool() {ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 5,1L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(3),Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());return executor;}
}

第一种,需要返回值的,那只能是 Callable

public class MyFuture implements Callable<String> {@Overridepublic String call() throws Exception {if (true) {Thread.sleep(1000);int i = 1 / 0;}return "线程池中的任务执行完成";}
}

需要注意的是,这里的 MyFuture 代码块中,并没有去 try catch,从而可以将异常带到controller层,使用@RestControllerAdvice进行捕获

    @GetMapping("/threadpool")public String threadpool() throws ExecutionException, InterruptedException {MyFuture myFuture = new MyFuture();FutureTask<String> futureTask = new FutureTask<>(myFuture);threadPoolExecutor.submit(futureTask);String s = futureTask.get();return "threadpool 请求成功";}

那么如果try catch了会怎么样呢?那自然RestControllerAdvice 就捕获不到,就会 return “threadpool 请求成功”;

第二种,不需要返回值的,那就可以是 Runnable

public class MyRunnable implements Runnable {@Overridepublic void run() {//像这么写,是不会在控制台打印出异常信息的,当然,我们可以将代码使用try-catch包裹起来,然后在catch中打印异常信息ArrayList<String> strings = new ArrayList<>();strings.add("1");strings.add("2");System.out.println(strings.get(3));}
}

不需要返回值的,如何捕获线程池中的异常?

    @GetMapping("/threadpool3")public String threadpool3() throws ExecutionException, InterruptedException {MyRunnable myRunnable = new MyRunnable();Thread thread = new Thread(myRunnable);thread.setUncaughtExceptionHandler((t, e) -> {System.out.println("线程池中的异常被捕获到了--2" + e.getMessage());//控制台打印异常信息});thread.start();return "threadpool-myRunnable 请求成功";//这里会被执行}

但是记住,不论是什么异常捕获机制,都有疏漏的地方,就比如最后一个例子,当我们请求 /threadpool3 的时候,得到了 threadpool-myRunnable 请求成功 这段话,就真的达到我们想要的目的了么?线程池里面的任务执行的如何了?失败的话,只是被打印出来的日志,没有人去看也没用,所以说,最好的方式还是捕获到异常之后,发送一条消息到 钉钉群,或者是微信群 这种方式最为稳妥。

没有人会点击一个接口之后,立马去看日志,当我们发现线程池中的任务执行失败的时候,很可能是1个小时以后的事情了,那个时候再去翻找日志太麻烦,所以说及时通知到群里才是最可靠的

这篇关于异常处理相关心得的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1134666

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

sqlite3 相关知识

WAL 模式 VS 回滚模式 特性WAL 模式回滚模式(Rollback Journal)定义使用写前日志来记录变更。使用回滚日志来记录事务的所有修改。特点更高的并发性和性能;支持多读者和单写者。支持安全的事务回滚,但并发性较低。性能写入性能更好,尤其是读多写少的场景。写操作会造成较大的性能开销,尤其是在事务开始时。写入流程数据首先写入 WAL 文件,然后才从 WAL 刷新到主数据库。数据在开始

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容

1.访问位与修改位的题型(淘汰哪一页) 访问位:为1时表示在内存期间被访问过,为0时表示未被访问;修改位:为1时表示该页面自从被装入内存后被修改过,为0时表示未修改过。 置换页面时,最先置换访问位和修改位为00的,其次是01(没被访问但被修改过)的,之后是10(被访问了但没被修改过),最后是11。 2.内聚的类型 功能内聚:完成一个单一功能,各个部分协同工作,缺一不可。 顺序内聚:

Thymeleaf:生成静态文件及异常处理java.lang.NoClassDefFoundError: ognl/PropertyAccessor

我们需要引入包: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>sp

log4j2相关配置说明以及${sys:catalina.home}应用

${sys:catalina.home} 等价于 System.getProperty("catalina.home") 就是Tomcat的根目录:  C:\apache-tomcat-7.0.77 <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %msg%n" /> 2017-08-10

Node Linux相关安装

下载经编译好的文件cd /optwget https://nodejs.org/dist/v10.15.3/node-v10.15.3-linux-x64.tar.gztar -xvf node-v10.15.3-linux-x64.tar.gzln -s /opt/node-v10.15.3-linux-x64/bin/npm /usr/local/bin/ln -s /opt/nod

git ssh key相关

step1、进入.ssh文件夹   (windows下 下载git客户端)   cd ~/.ssh(windows mkdir ~/.ssh) step2、配置name和email git config --global user.name "你的名称"git config --global user.email "你的邮箱" step3、生成key ssh-keygen

深入理解数据库的 4NF:多值依赖与消除数据异常

在数据库设计中, "范式" 是一个常常被提到的重要概念。许多初学者在学习数据库设计时,经常听到第一范式(1NF)、第二范式(2NF)、第三范式(3NF)以及 BCNF(Boyce-Codd范式)。这些范式都旨在通过消除数据冗余和异常来优化数据库结构。然而,当我们谈到 4NF(第四范式)时,事情变得更加复杂。本文将带你深入了解 多值依赖 和 4NF,帮助你在数据库设计中消除更高级别的异常。 什么是

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法   消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法 [转载]原地址:http://blog.csdn.net/x605940745/article/details/17911115 消除SDK更新时的“