自定义异常的使用场景

news/2025/2/23 18:08:41/文章来源:https://www.cnblogs.com/throughFog/p/18732553

看到一些文章说不要使用异常代替正常的控制流,对这个一直都不太清楚,随即查了下,做下笔记。

核心原则:区分预期错误(Expected Errors)意外异常(Unexpected Exceptions)

预期错误应当显示处理:输入验证、业务规则检查等都属于预期内的错误,应该通过返回值、状态码或结果对象明确传递。

假设需要验证用户输入内容合法性,有两种方式:

方式一:使用异常处理,不好的做法,会使调用方处理起来麻烦

// 通过抛出异常表示验证失败
public void ValidateEmail(string email)
{if (!Regex.IsMatch(email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$")){throw new InvalidEmailException("邮箱格式错误");}
}// 调用方必须用 try-catch 处理正常逻辑
try
{ValidateEmail("invalid-email");Console.WriteLine("邮箱有效");
}
catch (InvalidEmailException ex)
{Console.WriteLine($"验证失败: {ex.Message}");
}

方式二:返回明确结果

// 返回一个结果对象,包含是否成功和错误信息
public ValidationResult ValidateEmail(string email)
{bool isValid = Regex.IsMatch(email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$");return new ValidationResult{IsValid = isValid,ErrorMessage = isValid ? null : "邮箱格式错误"};
}// 调用方直接处理结果,无需 try-catch
var result = ValidateEmail("invalid-email");
if (result.IsValid)
{Console.WriteLine("邮箱有效");
}
else
{Console.WriteLine($"验证失败: {result.ErrorMessage}");
}

滥用异常的坏处

  1. 性能问题,异常处理成本高昂,CLR需要手机堆栈跟踪(Stack Trace)、展开调用栈,相比较条件判断,要慢数百倍。
  2. 代码可读性低,使用try-catch处理正常流程,会让其他人误以为是意外错误,而非预期业务逻辑分支。
  3. 破坏代码结构,正常的控制流被打断,其他人不得不处理异常,导致代码难以维护

所有业务流程中的错误都不属于异常吗?

非也,本质还是判断错误的性质:是预期内的业务规则失败,还是需要中断当前流程的严重错误。比如:

场景一:某些业务错误需要立即终止当前操作,且不适合通过返回值逐层传递,此时异常是更直接的选择。
场景二:需统一处理的特定错误类型
通过自定义异常,可在全局异常过滤器中统一处理特定业务错误,返回标准化响应。例如:

// 自定义异常
public class InsufficientBalanceException : Exception
{public decimal RequiredAmount { get; }public InsufficientBalanceException(decimal required) : base($"余额不足,需支付 {required}") => RequiredAmount = required;
}// 全局异常过滤器
public class BusinessExceptionFilter : IExceptionFilter
{public void OnException(ExceptionContext context){if (context.Exception is InsufficientBalanceException ex){context.Result = new JsonResult(new{Code = 400,Message = ex.Message,RequiredAmount = ex.RequiredAmount});context.ExceptionHandled = true;}}
}

在判断是否使用自定义异常前,先问自己以下几个问题:

  1. 是否属于不可恢复的错误?
  2. 是否需要跨多层传递错误?
  3. 是否不属于预期内的业务规则失败?
  4. 是否需要强制调用方处理此错误?
  5. 发生频率是否很低?
    若有半数以上结果为“是”,则说明适合自定义异常。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/888500.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

字符串的编码及解码

1. 字符串的编码及解码解释str类型转换为bytes类型为编码bytes类型转换为str类型为解码2. 字符串的编码str类型转换为bytes类型使用字符串encode()方法语法格式:str.encode(encodeing= utf8,errors=strict/ignore/replace)出错方式:strict:严格的;报错。 ignore:忽略;rep…

3.正向传播与反向传播 - 学习率LR - Batch size - 激活函数 - 损失函数

正向传播尽量降低损失函数梯度梯度是一个向量(矢量),函数在一点处沿着该点的梯度方向变化最快,变化率最大。换而言之,自变量沿着梯度方向变化,能够使应变量(函数值)变化最大。如图:如果想要 w 下降最快就沿着梯度的负方向下降,就能降低损失函数方向传播更新各个参数的…

Qt报错error: member access into incomplete type QTcpSocket

现象解决办法 在mainwindow.cpp文件中添加头文件。 #include <QTcpSocket>

Spring Boot中如何优雅地读取Jar包中的Resources目录下的文件

在Java的Spring Boot项目中,我们经常需要从resources目录下读取配置文件或其他资源文件。在本地开发环境中,我们可以轻松地使用绝对路径访问这些文件,但项目一旦打包成Jar包并部署到服务器上,这种访问方式就失效了。 因此,掌握在Jar包中读取resources目录下文件的方法至关…

开学测试总结owo

经过这次的小测,在这次测试中,我个人认为最大的变化,就是逻辑性增强,sql语句的要求更多了, 这就反应了对于web应用开发这门课对我们专业的用处,还有,前端页面的美化,我认为前端代码,多 数交给AI就可以了,但主要是你自己要明白需求到底是什么,你要完成的项目是什么,…

get current user

02 - 从SpringSecurity中获取当前用户 一行搞定 SecurityContextHolder.getContext().getAuthentication().getPrincipal();这里自定义了一个UserDetailsImpl类实现UserDetails接口, 此时loadUserByUsername方法的返回对象的类型也要改成自定义类型(01篇最后那样), 不然报错。测…

自编译Frp 实现二次开发

在使用过程中,我们都是利用作者打包好的包,直接使用。但是现实中,我们可能需要对其进行二开。 因而,本文简单的为大家介绍下frp的二次开发。以修改frps dashboard为例。现在让我们一起来学习吧。修改之前的界面修改后效果 安装GO环境 因为,Frp是基于GO开发的,所以我们需要…

从黑盒到透明:AI Agent 运行监控实战!

你是否遇到过这样的情况:辛辛苦苦开发的 AI Agent 突然失灵了,却不知道是哪个环节出了问题?今天给家人们分享一下如何让 AI Agent 的运行过程透明化。 一、为什么要监控 AI Agent? 传统的对话系统就像一张预先画好的地图,用户只能按照既定路线前进。而 AI Agent 则像是一位…

[2025.2.23] 周记

引言在这周的面试当中,我遇到了几个不是很清楚的题目,回家之后进行学习发现了一些比较有意思的事情,在这里记录一下 这周还发现了一个很有帮助的Java知识网站:Java 基础 - 面向对象 | Java 全栈知识体系1.字符串和常量池 在这次面试当中遇到的一个原题就是 String i = "i&…

YOLOv5 的量化及部署 - RGB 专题

技术背景 YOLOv5 是一种高效的目标检测算法,尤其在实时目标检测任务中表现突出。YOLOv5 通过三种不同尺度的检测头分别处理大、中、小物体;检测头共包括三个关键任务:边界框回归、类别预测、置信度预测;每个检测头都会逐像素地使用三个 Anchor,以帮助算法更准确地预测物体…

Java基础学习(十七)

Java基础学习(十七):网络编程 目录Java基础学习(十七):网络编程概念IP端口号协议UDP 通信TCP 通信 本文为个人学习记录,内容学习自 黑马程序员概念定义:在网络通信协议下,不同计算机上运行的程序进行的数据传输 常见的软件架构:C/S 和 B/SC/S:Client/Server,在用户…

最小费用最大流问题的 SSP 算法

我们已经了解最大流问题,其目标是通过网络中的各条边传输流量,尽可能地从源点流向汇点。通过经典的算法,如 Ford-Fulkerson 增广,我们能够找到一种方式,最大化从源点到汇点的流量。 然而,最大流问题的基本形式并没有考虑流动的成本。一个图的最大流值是一个固定数,可以由…