如何处理三层框架的异常
这个图 是从网站上保存下来的。
Scenario | Description | Expected Result |
1 | Application called a stored procedure. | Happy path; everything should work fine. |
2 | Exception Raised by Database Management System such as Primary Key violated or Object does not exist, etc. | System should log the thrown exception in a sink (Text File). Replace the Exception with a User friendly Message and propagate it to UI passing through the Business Logic Layer. |
3 | Based upon some certain validation check / business rule a Custom Error is raised from Stored Procedure. | Thrown Custom Error message should be propagated to UI without Logging assuming these error messages will be some kind of alternative flows instead of real exception. |
4 | While processing the request, an error occurred in Business Logic such as Divide-by-zero, Object not set, Null reference exception, etc. | System should log the thrown exception in a sink (Text File). Replace the Exception with a User friendly Message and should propagate that to UI. |
5 | Based upon some certain business validation check, a custom exception was thrown from Business Logic Layer. | Thrown Custom Error message should be propagated to UI without Logging assuming these error messages will be some kind of alternative flows instead of real exception. |
6 | While processing the request an error occurred in UI. For example, Null reference exception, etc. |
System should log the thrown exception in a sink (Text File). Replace the Exception with a User friendly Message and should propagate that to UI. |
参考地址:https://www.codeproject.com/articles/85569/exception-handling-in-3-tier-architecture
标题:Exception Handling in 3-Tier Architecture
思想是:使用自定义异常替代原始的异常信息,如数据库错误信息,系统错误,组件错误等。
替换原始异常的信息,然后将异常传递到UI层,将更友善的信息展示给用户;
该记录的异常要记录到日志系统;
不需要记录的异常信息要直接抛给用户,让用户知道错在哪里;
需要仔细区分,哪些异常应该抛给用户,哪些异常应该进行替换展示友好信息,并记录异常信息,通知开发人员处理;
==========================================
参考:How to rethrow exceptions in a program with multiple layers?
地址:https://stackoverflow.com/questions/14060042/how-to-rethrow-exceptions-in-a-program-with-multiple-layers
(我认为)建议您抛出一个新的更简单的异常,就是将异常从较低层转换为新的、更高级别的异常,以便在外层中使用。较低级别的异常不适合在程序的上层使用。
例如,在LINQto实体中,当序列没有元素时,方法Single()将抛出InvalidOperationException。但是,这种异常类型非常常见,因此很难在用户界面级别捕获它:如何区分引发此异常的不同可能性(例如,修改只读集合)?解决方案是将异常转换为应用程序可以轻松处理的另一种(新的、用户定义的)类型。
Here is a simple example of the idea:
public class MyUserService { public User GetById(int id) { try { using(var ctx = new ModelContainer()) { return ctx.Where(u => u.Id == id).Single(); } } catch(InvalidOperationException) { // OOPs, there is no user with the given id! throw new UserNotFoundException(id); } } }
然后,Program层可以捕获UserNotFoundException并立即知道发生了什么,从而找到向用户解释错误的最佳方法。细节将取决于程序的确切结构,但类似的内容将在ASP.NETMVC应用程序中工作:
public class MyUserController : Controller { private MyUserService Service = new MyUserService(); public ActionResult Details(int id) { User user; try { user = Service.GetById(id); } catch(UserNotFoundException) { // Oops, there is no such user. Return a 404 error // Note that we do not care about the InvalidOperationException // that was thrown inside GetById return HttpNotFound("The user does not exist!"); } // If we reach here we have a valid user return View(user); } }
-----------------------------------------------------------------------------------------
有更多的方法可以使用不同类型的异常处理。在功能上,您应该定义哪些层在异常情况下必须做什么。
就像数据层=>一样,除了DataException或SQLException之外,不要抛出其他任何东西。记录它们并将一个通用数据库异常抛回UI。
业务层=>日志并重新抛出简单的业务异常UI层=>只捕获业务异常并在业务异常内的消息中警告它。
一旦定义了所有这些,您就可以使用您所学到的和问题中的总结来构建它。
--------------------------------------------------------------
20200602
最近的一些想法:
1,底层三层全部不捕获异常,在UI层,用try catch统一捕获;
2,在项目中自定义一些异常,自定义的异常抛出的信息都可以直接展示给用户,比如因状态限制,删除失败的原因;
3,数据库类异常、网络类异常、代码类异常、进行异常信息替换,不让用户看到具体的表字段,表名,资源地址,代码信息等;
-------------------------------------------------------------------------------------------
20200730
最新的想法:
所有返回类型,继承一个基础类:基础类提供:errorCode,errorMsg,innerError属性;
如果errorCode=0,程序正常执行;
如果errorCode=-1,业务性异常,消息可以展示给客户看;
如果errorCode=-2,是程序性异常,消息必须进行替换后展示,需要记录日志。innerError可以记录具体的内部异常信息,方便记录日志;
------------------------------------------------------------------------------------------
20200918
最新的想法
ErrorMsg属性可以建两个,一个用来写可以给客户看的内容,一个写不可以给客户看的内容,用来记录日志。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
2017-12-07 一些编程
2016-12-07 asp.net大文件上传与上传文件进度条问题
2016-12-07 按enter执行click或者搜索问题