Distinguish Business Exceptions from Technical 21

2023-05-16

Distinguish Business Exceptions from Technical

There are basically two reasons that things go wrong at runtime: technical problems that prevent us from using the application and business logic that prevents us from misusing the application. Most modern languages, such as LISP, Java, Smalltalk, and C#, use exceptions to signal both these situations. However, the two situations are so different that they should be carefully held apart. It is a potential source of confusion to represent them both using the same exception hierarchy, not to mention the same exception class.

An unresolvable technical problem can occur when there is a programming error. For example, if you try to access element 83 from an array of size 17, then the program is clearly off track, and some exception should result. The subtler version is calling some library code with inappropriate arguments, causing the same situation on the inside of the library.

It would be a mistake to attempt to resolve these situations you caused yourself. Instead we let the exception bubble up to the highest architectural level and let some general exception-handling mechanism do what it can to ensure the system is in a safe state, such as rolling back a transaction, logging and alerting administration, and reporting back (politely) to the user.

A variant of this situation is when you are in the “library situation” and a caller has broken the contract of your method, e.g., passing a totally bizarre argument or not having a dependent object set up properly. This is on a par with accessing 83rd element from 17: the caller should have checked; not doing so is a programmer error on the client side. The proper response is to throw a technical exception.

A different, but still technical, situation is when the program cannot proceed because of a problem in the execution environment, such as an unresponsive database. In this situation you must assume that the infrastructure did what it could to resolve the situation — repairing connections and retrying a reasonable number of times — and failed. Even if the cause is different, the situation for the calling code is similar: there is little it can do about it. So, we signal the situation through an exception that we let bubble up to the general exception handling mechanism.

In contrast to these, we have the situation where you cannot complete the call for a domain-logical reason. In this case we have encountered a situation that is an exception, i.e., unusual and undesirable, but not bizarre or programmatically in error. For example, if I try to withdraw money from an account with insufficient funds. In other words, this kind of situation is a part of the contract, and throwing an exception is just an alternative return path that is part of the model and that the client should be aware of and be prepared to handle. For these situations it is appropriate to create a specific exception or a separate exception hierarchy so that the client can handle the situation on its own terms.

Mixing technical exceptions and business exceptions in the same hierarchy blurs the distinction and confuses the caller about what the method contract is, what conditions it is required to ensure before calling, and what situations it is supposed to handle. Separating the cases gives clarity and increases the chances that technical exceptions will be handled by some application framework, while the business domain exceptions actually are considered and handled by the client code.

By Dan Bergh Johnsson

区分业务例外和技术例外
运行时出错的原因基本上有两个:阻止我们使用应用程序的技术问题和阻止我们滥用应用程序的业务逻辑。大多数现代语言,如LISP、Java、Smalltalk和C#,都使用异常来表示这两种情况。然而,这两种情况是如此不同,应该小心地将它们分开。使用相同的异常层次结构来表示它们,更不用说使用同一个异常类了,这可能会造成混淆。
当出现编程错误时,可能会出现无法解决的技术问题。例如,如果您试图从大小为17的数组中访问元素83,那么程序显然偏离了轨道,应该会出现一些异常。更微妙的版本是用不适当的参数调用一些库代码,导致库内部出现同样的情况。
试图解决你自己造成的这些情况是错误的。相反,我们让异常上升到最高的体系结构级别,并让一些通用的异常处理机制尽其所能确保系统处于安全状态,例如回滚事务、日志记录和警报管理,以及(礼貌地)向用户报告。
这种情况的一种变体是,当您处于“库情况”时,调用方违反了您方法的约定,例如,传递了一个完全奇怪的参数或没有正确设置依赖对象。这与访问17中的第83个元素是一样的:调用者应该已经检查过了;不这样做是客户端的程序员错误。正确的回应是抛出一个技术异常。
另一种不同但仍然是技术性的情况是,由于执行环境中的问题,例如数据库没有响应,程序无法继续。在这种情况下,您必须假设基础设施已经尽其所能解决了这种情况——修复连接并重试合理的次数——但失败了。即使原因不同,调用代码的情况也是相似的:它对此无能为力。因此,我们通过一个异常向通用异常处理机制发出信号。
与此相反,我们的情况是,由于域逻辑原因,您无法完成调用。在这种情况下,我们遇到了一种例外情况,即不寻常和不可取的情况,但并不奇怪或程序错误。例如,如果我试图从资金不足的账户中提取资金。换句话说,这种情况是合同的一部分,抛出异常只是一种替代的返回路径,它是模型的一部分并且客户应该意识到并准备好处理。对于这些情况,创建一个特定的异常或单独的异常层次结构是合适的,这样客户端就可以根据自己的条件处理这种情况。
将技术异常和业务异常混合在同一层次结构中会模糊区别,并使调用者混淆方法约定是什么、在调用之前需要确保什么条件以及应该处理什么情况。将案例分开可以使情况变得清晰,并增加了由某些应用程序框架处理技术异常的机会,而业务域异常实际上是由客户端代码考虑和处理的。
作者Dan Bergh Johnsson

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Distinguish Business Exceptions from Technical 21 的相关文章

随机推荐

  • mac系统中怎么把显示在桌面上的磁盘图标取消掉?

    问题现象 xff1a 安装一些软件时 xff0c 桌面上总会出现外置磁盘图标如图1 下面就简单介绍下怎样取消这种外置图标 图1 解决方案 xff1a finder xff0d 偏好设置 xff0d 通用 xff0d 外置设置 取消前面对话框
  • tensorflow深度学习实战笔记(三):使用tensorflow lite把训练好的模型移植到手机端,编译成apk文件

    目录 一 准备工作 1 1模型训练 1 2模型固化和pb转tflite 1 3下载tensorflow源码 1 4安装android studio 二 在Android studio中进行开发 2 1修改app的build gradle文件
  • nvidia和cuda对应以及cuda和cuDNN对应版本

  • 修改spring Boot启动时的默认图案Banner

    一 修改Banner spring Boot启动的时候会有一个默认的启动图案 如下图 39 39 39 39 96 39 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • Java线程池自学手册Executor的使用

    准备做一个系列文章 xff0c 将零散的知识整理起来分享给大家 xff0c 希望给大家的工作和学习带来帮助 目录 1 Executor 2 ExecutorService 3 Executors 4 ThreadPoolExecutor 5
  • 常用开发资源整理(更新日:2017/4/26)

    说明 xff1a 为了方便 xff0c 今后将工作中用到一些常用的资源链接进行整理 xff0c 初衷是想发些各版本的冷资源 xff0c 免得在需要的时候花大量时间寻找 一 开发语言 1 Spring各版本压缩包下载 http repo sp
  • 博客地址迁移www.xiangquba.cn

    大家好 xff0c 非常感谢大家一直以来对我的关注 xff0c 博客有一年时间没有更新了 xff0c 其实我并没有停止分享 xff0c 只是这一年时间并没有在csdn上更新 xff0c 原因是因为起初csdn有一个自己给csdn发送短信绑定
  • FreeRTOS 任务函数里面的死循环

    任务函数是一个无限循环且不带返回值的函数 任务必须是死循环 xff0c 否则任务将经过 LR 返回 xff0c 如果 LR 指向了非法内存就会产生HardFault Handler xff0c 而 FreeRTOS 指向一个死循环 xff0
  • 使用libcurl异步发送http请求

    在工作中需要完成一个工具 xff0c 该工具主要的用途就是向指定的服务器和端口发送http请求 xff0c 为了提高性能 xff0c 采用多线程的方式进行 xff0c 同时采用libcurl的异步形式 代码如下 xff0c 在其中添加一些注
  • 【Kubernetes】K8S实践感受HPA的功能

    1 确保metrics server安装好 span class token punctuation span root 64 jdmaster span class token punctuation span span class to
  • 拓扑结构与IP地址划分

    拓扑结构 分为总线型 星型和环形 环形要比星型的可靠性更高 公司的网络拓扑结构是星型 中心是交换机 IP发展 第一阶段 分为A E类 第二阶段 子网划分 第三阶段 无类域间路由 现在多采用这一种 不仅满足大网分小 也满足子网合成超网 无类域
  • 多网卡udp绑定问题

    在多网卡机器上 udp包 协议会自动根据路由最优选择从哪个网卡发数据包出去 即使你在此之前把改socket绑定到了另一个网卡上 参考文章 https blog csdn net Scarlett OHara article details
  • QIODevice::readyRead()

    void QIODevice readyRead This signal is emitted once every time new data is available for reading from the device 每次当新数据
  • 论文投稿参考——如何撰写和发表SCI论文

    如何撰写和发表SCI论文 汪景秀 提要 对从事基础研究的科学工作者 能否在SCI收录的杂志发表论文 是能否进入学术前沿 在国际公认的同一个平台上参与学术竞争 做出原创性贡献的一个基本标志 那么怎样的论文才是合格的 xff1f 本文提出一些建
  • Win7电脑遇到蓝屏,并报错:IRQL NOT LESS OR EQUAL

    这一阵电脑老是蓝屏 xff0c 重启后window和360都检测到之前发生过蓝屏 xff0c 但是都不能够修复成功 一开始直接在百度上搜电脑蓝屏 xff0c 也没啥大的收获 直到有次注意到蓝屏时还有错误类型 xff1a IRQL NOT L
  • VS使用收获总结

    诊断工具在调试 gt 窗口 gt 显示诊断工具 报CL exe问题 可能是IDE的问题 比如写一个最简单的hello world代码来进行检验 可以在查找时使用正则表达式 xff0c 比如想要搜索 行尾为 61 1 xff1b 的文本 可以
  • 进程间的mutex

    设两个进程共用一个临界资源的互斥信号量mutex 61 1 xff0c 当mutex xff1d xff0d 1时表示 一个进程进入了临界区 xff0c 另一个进程等待 没有一个进程进入临界区 两个进程都进入临界区 两个进程都在等待 互斥信
  • 128种chatGPT可以为人类做的事情

    1 充当英语翻译 充当英语翻译员 拼写纠正员和改进员 xff0c 我会用任何语言与你交谈 xff0c 你会检测语言 xff0c 翻译它并用我的文本的更正和 改进版本用英语回答 2 充当词典 充当英英词典 xff0c 对于给出的英文单词 xf
  • thing_10

    Choose Your Tools with Care Modern applications are very rarely built from scratch They are assembled using existing too
  • Distinguish Business Exceptions from Technical 21

    Distinguish Business Exceptions from Technical There are basically two reasons that things go wrong at runtime technical