108 老生常谈的异常被“吞掉“

2024-03-19 14:52
文章标签 异常 108 吞掉 老生常谈

本文主要是介绍108 老生常谈的异常被“吞掉“,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

这是一个很经典的也经常出现的问题了, 代码里面 发生了异常, 但是 异常被吞掉了, 然后 你可能就回感觉到 很莫名其妙 

就好比 我现在有一个 Service.doBiz 是加了事务的, 然后里面抛出了异常, 但是 在Service.doBiz的调用方处理了这个异常, 并且没有在日志中体现 

然后出现的问题就是, 你会发现 Service.doBiz 莫名其妙的回滚了, 但是 你有不知道异常是什么, 特别是 可以看一下我这里的情况 

呵呵 这是一个老生常谈的问题了, 但是 我这次碰到了, 并且 还懵了我 几分钟, 呵呵 当时特意打了一个 todo, 说是要记录一下  

 

 

测试用例

/*** Test18TryFinally** @author Jerry.X.He <970655147@qq.com>* @version 1.0* @date 2020-12-19 16:51*/
public class Test18TryFinally {// Test18TryFinallypublic static void main(String[] args) {doWithRecord((arg) -> {txExecute(innerArg -> {try {String usernameLike = "jerry";String sqlTemplate = " select * from user where username like '%s' or name like '%s' ";String str = String.format(sqlTemplate, usernameLike);System.out.println(" doQuery for : " + str);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                    throw e;} finally {doSilently(" finally ");}});});}public static void txExecute(Consumer<Void> func) {try {func.accept(null);} catch (Exception e) {System.err.println(" tx rollback ");throw e;}}/*** doWithRecord** @param func func* @return void* @author Jerry.X.He* @date 2020-12-19 17:10*/public static void doWithRecord(Consumer<Void> func) {AtomicBoolean record = new AtomicBoolean(true);try {func.accept(null);} catch (Exception e) {record.set(false);// record error message } finally {doSilently(" doSaveRecord : " + record);}}/*** 相关从日志里面 日志看不到的东西** @param args args* @return void* @author Jerry.X.He* @date 2020-12-20 11:13*/public static void doSilently(String args) {// doSilentlySystem.setOut(new PrintStream(new NullOutputStream()));System.out.println(args);}}

 

用例效果大致如下 

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTEwMzkzMzI=,size_16,color_FFFFFF,t_70

 

就类似于这种情况, 业务代码块里面抛出了异常, 是直接 try-fially 处理的, 也就是 如果出现了异常会直接 抛出去 

事务处理这边检测到了 异常, 是处理事务这边的业务, 回滚相关业务操作, 然后 将异常抛出去 

然后来到了 doWithRecord[这里只是一个模拟, 类似于一些基础工具模块], 类似于有一个任务记录, 需要执行这个任务记录, 任务执行之前, 之后会做一些事情, 发生了异常会做一些事情, 将这些"模板化"起来 

可以看到的是 doWithRecord 里面是记录了任务执行失败, 以及一些异常信息, 但是 没有在日志中体现出来, 要找具体的体现的话 是需要在 record 中去寻找 

 

但是 假设是对 record 这块的情况不太了解的开发来看的话, 这块 就回很懵, 因为 他只看到了 日志里面什么异常情况都没有, 但是事务回滚了, 并且 业务代码这边是 try-finally 无法在异常处打断点 

但是 如果是对 record 这部分有一些了解的话, 那可能稍微好点, 可能知道 从 record 里面取查询, 看下 异常信息 

反正 我这次是 吃了一点亏, 伤到了 要记录一下 ... 

 

我个人认为是可以在 doWithRecord 里面添加一下日志处理的, 因为这属于一些 基础服务的代码, 业务开发这边未必会仔细的去看这块的代码, 一般应该都是 很信任这块的代码, 然后就导致了 一些情况下 思路没对的话, 可能会 绕很久 

如果是 一些确实是可以 ignore 的异常, 这种 "吞掉"[当然这里是处理了的, 只是不太明显] 的处理, 那就无所谓了 

 

 

完 

 

 

 

 

这篇关于108 老生常谈的异常被“吞掉“的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

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

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

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

深入理解数据库的 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更新时的“

JVM 常见异常及内存诊断

栈内存溢出 栈内存大小设置:-Xss size 默认除了window以外的所有操作系统默认情况大小为 1MB,window 的默认大小依赖于虚拟机内存。 栈帧过多导致栈内存溢出 下述示例代码,由于递归深度没有限制且没有设置出口,每次方法的调用都会产生一个栈帧导致了创建的栈帧过多,而导致内存溢出(StackOverflowError)。 示例代码: 运行结果: 栈帧过大导致栈内存

org.hibernate.hql.ast.QuerySyntaxException:is not mapped 异常总结

org.hibernate.hql.ast.QuerySyntaxException: User is not mapped [select u from User u where u.userName=:userName and u.password=:password] 上面的异常的抛出主要有几个方面:1、最容易想到的,就是你的from是实体类而不是表名,这个应该大家都知道,注意

C++第四十七弹---深入理解异常机制:try, catch, throw全面解析

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】 目录 1.C语言传统的处理错误的方式 2.C++异常概念 3. 异常的使用 3.1 异常的抛出和捕获 3.2 异常的重新抛出 3.3 异常安全 3.4 异常规范 4.自定义异常体系 5.C++标准库的异常体系 1.C语言传统的处理错误的方式 传统的错误处理机制:

argodb自定义函数读取hdfs文件的注意点,避免FileSystem已关闭异常

一、问题描述 一位同学反馈,他写的argo存过中调用了一个自定义函数,函数会加载hdfs上的一个文件,但有些节点会报FileSystem closed异常,同时有时任务会成功,有时会失败。 二、问题分析 argodb的计算引擎是基于spark的定制化引擎,对于自定义函数的调用跟hive on spark的是一致的。udf要通过反射生成实例,然后迭代调用evaluate。通过代码分析,udf在

flume系列之:记录一次flume agent进程被异常oom kill -9的原因定位

flume系列之:记录一次flume agent进程被异常oom kill -9的原因定位 一、背景二、定位问题三、解决方法 一、背景 flume系列之:定位flume没有关闭某个时间点生成的tmp文件的原因,并制定解决方案在博主上面这篇文章的基础上,在机器内存、cpu资源、flume agent资源都足够的情况下,flume agent又出现了tmp文件无法关闭的情况 二、

com.google.gson.JsonSyntaxException:java.lang.IllegalStateException异常

用Gson解析json数据的时候,遇到一个异常,如下图: 这个异常很简单,就是你的封装json数据的javabean没有写对,你仔细查看一下javabean就可以了 比如:我的解析的代码是             Gson gson = new Gson();             ForgetJson rb = gson.fromJson(agResult.mstrJson, For