当前位置: 首页 > 编程日记 > 正文

解析大型.NET ERP系统 设计异常处理模块

异常处理模块是大型系统必备的一个组件,精心设计的异常处理模块可提高系统的健壮性。下面从我理解的角度,谈谈异常处理的方方面面。我的设计仅仅限定于Windows Forms,供参考。

1 定义异常类型

.NET 框架定义很多异常类型,ERP系统中根据实际的需要,我们再增加一些自定义的异常类型。

数据库访问异常:LLBL Gen Pro已经定义几种常见的异常类型,常见的异常类型及其作用简介。

ORMConcurrencyException     并发异常,更新实体时实体已经被删除,删除时有约束无法删除
ORMEntityOutOfSyncException. (Adapter) 实体保存之后没有重新读取,使用它的属性时抛出ORMEntityIsDeletedException   实体已经删除,但仍然访问它的属性
ORMFieldIsNullException.  在实体的属性值设为NULL之后,仍然去访问它的属性性
ORMEntityValidationException  自定义异常
ORMFieldIsReadonlyException  给只读的属性赋值
ORMInheritanceInfoException 查询执行过程中检测到错误
ORMQueryConstructionException ORM框架构造动态查询(Dynamic Query Engine )失败时ORMQueryExecutionException  ORM框架执行动态查询(Dynamic Query Engine )失败时
ORMRelationException  关系设定错误
ORMSecurityException 用于授权(Authorization)失败后
ORMValueTypeMismatchException 属性的值与类型不匹配

业务逻辑异常: 定义应用程序中的业务逻辑异常类型

AccessDeniedException 模块或功能当前登入用户无权限访问
CrystalReportException 水晶报表的运行库加载失败,报表连接数据库失败,报表公式解析失败等异常
EntityValidationException  业务对象验证失败
FieldValidationException  业务对象的属性验证失败
LicenseException  许可证授权异常
FtpException: 文件服务器连接失败或授权失败等异常

2 封装异常信息

在系统抛出异常时,我们需要知道抛出异常的程序的完整信息,比如程序版本,最后更新时间,发生异常的堆栈等,有了这些信息,技术支持或程序员可以快速定位异常,分析可能的原因。

为此目的,定义一个异常信息封装类,包含传入异常,封装更丰富的异常信息。

public sealed class ExceptionDetail
{private System.Exception _exception;private void Initialize(){if (this._exception != null){builder = builder.Append(format).Replace("\n", "\r\n");builder.Append(string.Format("Date: {0} {1}\r\n", DateTime.Today.ToShortDateString(), DateTime.Now.ToLongTimeString()));builder.Append(string.Format("Version: {0} ({1})\r\n", AssemblyVersion.Version, File.GetLastWriteTime(typeof(AssemblyVersion).Assembly.Location)));builder.Append(string.Format("Source: {0}\r\n", innerException.Source));builder.Append(string.Format("Class: {0}\r\n", (innerException.TargetSite != null) ? innerException.TargetSite.DeclaringType.ToString() : null));builder.Append(string.Format("Member Type: {0}\r\n", (innerException.TargetSite != null) ? innerException.TargetSite.MemberType.ToString() : null));builder.Append(string.Format("Member Name: {0}\r\n", innerException.TargetSite));builder.Append(string.Format("Exception Type: {0}\r\n", innerException.GetType().FullName));builder.Append(string.Format("Data: {0}\r\n", obj2));builder.Append("\r\n");builder.Append(string.Format("Exception: {0}", message));}}
}

3  捕获系统抛出的异常

对Windows Forms程序,可以通过两个属性设定完成对系统异常的捕获。

CustomExceptionHandler eh = new CustomExceptionHandler();
Application.ThreadException += new ThreadExceptionEventHandler(eh.OnThreadException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

CustomExceptionHandler 是一个处理异常信息密封类,源代码如下,目的是为了统一系统的异常错误提示界面。

internal sealed class CustomExceptionHandler
{public bool IsDebug = false;public CustomExceptionHandler(){}//Handle the exception  eventpublic void OnThreadException(object sender, ThreadExceptionEventArgs t){if (IsDebug) 
Debug.Assert(false, t.Exception.Message, t.Exception.StackTrace); DialogResult result = DialogResult.Cancel;try{result = this.ShowThreadExceptionDialog(t.Exception);}catch{try{result = MessageBox.Show(string.Format("{0}\r\n\r\n{1}", t.Exception.Message, t.Exception.StackTrace), "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Error);}finally{Application.Exit();}}if (result == DialogResult.Abort) Application.Exit();}private DialogResult ShowThreadExceptionDialog(Exception e){return DialogResult.Cancel;}}
 

异常显示对话框显示异常,参考下面的界面。

image

4  程序中可通过throw语句抛出异常,实现N层回滚

保存新实体对象时,判断数据是否重复:

if (salesContract.IsNew)
{ISalesContractManager salesContractManager = CreateProxyInstance<ISalesContractManager>();if (salesContractManager.IsSalesContractExist(salesContract.ContractNo))throw new RecordDuplicatedException(salesContract.ContractNo, "Cotract No. is already used");
}

发生属性改变事件时,触发验证:

public override bool ValidateFieldValue(IEntityCore involvedEntity, int fieldIndex, object value)
{bool result = base.ValidateFieldValue(involvedEntity, fieldIndex, value);if (!result) return false;switch ((SalesContractFieldIndex) fieldIndex){case SalesContractFieldIndex.CustomerNo:return this.ValidateCustomerNo((string) value);}return true;
}private bool ValidateCustomerNo(string value)
{if (!string.IsNullOrEmpty(value)){ICustomerManager customerManager = ClientProxyFactory.CreateProxyInstance<ICustomerManager>();customerManager.ValidateCustomerNo(Shared.CurrentUserSessionId, value);}return true;
}
 

Windows Forms异常处理的核心部分在本篇的第三部分,设置捕获系统抛出的异常。

相关文章:

内含福利|CSDN 携手字节跳动:云原生Meetup北京站报名热烈启动,1月8日见!

伴随云原生技术的成熟与落地&#xff0c;越来越多框架、中间件等开源项目相继涌现&#xff0c;帮助开发者和企业有效解决业务问题。2022年1月8日&#xff0c;CSDN携手字节跳动基础架构&#xff0c;将在北京举办第四场云原生线下Meetup。在这里&#xff0c;您可以与众多开源技术…

用Thymeleaf在前台下拉列表取值

转自&#xff1a;https://blog.csdn.net/u013600907/article/details/76165748转载于:https://www.cnblogs.com/sharpest/p/8875698.html

PHP使用JSON

JSON 基础 简 单地说&#xff0c;JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串&#xff0c;然后就可以在函数之间轻松地传递这个字符串&#xff0c;或者在异步应用程序中将字符串从 Web 客户机传递给服务器端程序。这个字符串看起来有点儿古怪&#xff08;稍后会看…

(原创)Python文件与文件系统系列(5)——stat模块

stat模块中定义了许多的常量和函数&#xff0c;可以帮助解释 os.stat()、os.fstat()、os.lstat()等函数返回的 st_result 类型的对象。 通常使用 os.path.is*() 这类函数来测试一个文件的类型&#xff0c;这些方法对同一个文件进行多次测试时&#xff0c;stat()系统调用都是不可…

Azure Neural TTS能让AI语音自然逼真到什么程度?

摘要&#xff1a;微软Azure Neural TTS让AI语音像真人一样富有感情&#xff0c;自然逼真。 Neural TTS&#xff08;神经网络文本转语音&#xff09;是微软Azure认知服务的强大语音合成功能&#xff0c;自推出以来&#xff0c;已被广泛应用于从语音助手、新闻阅读到有声读物创作…

ReentrantLock与synchronized

1、ReentrantLock 拥有Synchronized相同的并发性和内存语义&#xff0c;此外还多了 锁投票&#xff0c;定时锁等候和中断锁等候线程A和B都要获取对象O的锁定&#xff0c;假设A获取了对象O锁&#xff0c;B将等待A释放对O的锁定&#xff0c;如果使用 synchronized &#xff0c;如…

EXT按钮事件

在EXT中&#xff0c;当我们要为按钮点击添加处理function的时候&#xff0c;可以看到一般人的实现分成2类&#xff1a;1.使用onClick: function xx()2.使用handler: function xx()完成后&#xff0c;我们会发现&#xff0c;无论用哪一种实现&#xff0c;再点击按钮时都能触发xx…

浅谈HTTP中Get与Post的区别

Http定义了与服务器交互的不同方法&#xff0c;最基本的方法有4种&#xff0c;分别是GET&#xff0c;POST&#xff0c;PUT&#xff0c;DELETE。URL全称是资源描述符&#xff0c;我们可以这样认为&#xff1a;一个URL地址&#xff0c;它用于描述一个网络上的资源&#xff0c;而H…

达摩院年终预测重磅出炉:AI for Science 高居榜首,2022 十大科技趋势!

整理 | 郑丽媛出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;作为“一所探索科技未知的研究院”&#xff0c;阿里巴巴达摩院成立至今已经四年了。这四年来&#xff0c;达摩院秉持着“探索科技位置&#xff0c;以人类愿景为驱动力&#xff0c;开展基础科学和颠覆式…

TensorFlow——入门基础

TensorFlow原理&#xff1a; TensorFlow使用Graph来描述计算任务,图中的节点被称之为op.一个op可以接受0或多个tensor作为输入,也可产生0或多个tensor作为输出.任何一个Graph要想运行,都必须借助上下文Session.通过Session启动Graph,并将Graph中的op分发到CPU或GPU上,借助Sessi…

EXT iconCls说明

今天学习ext 看examples中的事例&#xff0c;其中有一个地方是这样写的&#xff1a; new ButtonPanel( Icon Only, [{ iconCls: add16 },{ iconCls: add24, scale: medium },{ …

25个好用到爆的一行 Python 代码,建议收藏

作者 | 欣一来源 | Pyhton爱好集中营在学习Python的过程当中&#xff0c;有很多复杂的任务其实只需要一行代码就可以解决&#xff0c;那么今天小编我就来给大家介绍实用的一行Python代码&#xff0c;希望对大家能够有所帮助。1.两个字典的合并x {a: 1, b: 2} y {c: 3, d: 4}将…

【工业串口和网络软件通讯平台(SuperIO)教程】七.二次开发服务驱动

SuperIO相关资料下载&#xff1a;http://pan.baidu.com/s/1pJ7lZWf 1.1 服务接口的作用 围绕着设备驱动模块采集的数据&#xff0c;根据需求提供多种应用服务&#xff0c;例如&#xff1a;数据上传服务、数据请求服务、4-20mA服务、短信服务、LED服务以及OPC服务等。保障数…

usermod命令,用户密码管理和mkpasswd命令

2019独角兽企业重金招聘Python工程师标准>>> usermod 设置扩展组 概念&#xff1a;更改用户属性的一个命令。 用法&#xff1a;usermod [选项] 后面跟你需要操作的内容 [用户名] 选项&#xff1a;-c, --comment 注释 GECOS 字段的新值-d, --home HO…

extjs关于jsonreader

在JavaScript中&#xff0c;JSON是一种非常重要的数据格式&#xff0c;key:value的形式比XML那种复杂的标签结构更容易理解&#xff0c;代码量也更小&#xff0c;很多人倾向于使用它作为EXT的数据交换格式。JsonReader支持分页&#xff0c;与JSON数据对应格式如下&#xff1a;t…

求逆元 - HNU 13412 Cookie Counter

Cookie Counter Problems Link: http://acm.hnu.cn/online/?actionproblem&typeshow&id13412&courseid0 Mean: 将N分为D份&#xff0c;每份不超过X&#xff0c;有多少种分法&#xff1f; analyse: 首先我们想到的是迭代&#xff0c;但是数据太大&#xff0c;…

IEEE 发布年终总结,AI 奇迹不再是故事

编译 | 禾木木 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; 2021 年&#xff0c;人工智能奇迹不再只是故事&#xff01; 人工智能正在迅速融入各行各业&#xff0c;IEEE Spectrum 总结了 2021 年 10 篇最受读者欢迎的 AI 文章&#xff0c;按时间排名&#xff0c;…

一则利用内核漏洞获取root权限的案例【转】

转自&#xff1a;https://blog.csdn.net/u014089131/article/details/73933649 目录(?)[-] 漏洞描述漏洞的影响范围漏洞曝光时间漏洞产生的原因漏洞的利用exploit代码分析kernel 最近出了一个新的本地提权安全漏洞CVE-2013-1763&#xff0c;影响范围比较广泛&#xff0c;ubunt…

Ext.data库

Ext.data 库主要包括以下几个类&#xff1a;Ext.data.Store >DataSetExt.data.Record >DataSet.RowExt.data.DataProxy >SqlConnectionExt.data.DataReader >SqlDataAdapter以下分别进行介绍:1.Ext.data.Record可以用来定义一行数据的格式,它有几个重要的属性和方法…

2021年最有用的数据清洗 Python 库

作者 | 周萝卜来源 | 萝卜大杂烩大多数调查表明&#xff0c;数据科学家和数据分析师需要花费 70-80% 的时间来清理和准备数据以进行分析。对于许多数据工作者来说&#xff0c;数据的清理和准备也往往是他们工作中最不喜欢的部分&#xff0c;因此他们将另外 20-30% 的时间花在抱…

组合与继承之重写方法和字段

为什么80%的码农都做不了架构师&#xff1f;>>> 接上篇blog&#xff0c;scala里的字段和方法属于相同的命名空间&#xff0c;这让字段可以重写无参数方法。例如&#xff0c;你可以通过改变ArrayElement类中contents的实现将其从一个方法变为一个字段&#xff0c;而…

20165334 四则运算阶段性总结(第二周)

四则运算阶段性总结&#xff08;第二周&#xff09; 结对对象 学号 &#xff1a;20165334 姓名 &#xff1a; 李天龙 担任角色 &#xff08;驾驶员&#xff09;&#xff1a;李天龙 &#xff08;副驾驶&#xff09;&#xff1a;陈国超 一、实验实现步骤 整数计算类分数计算类自动…

取消掉Transfer-Encoding:chunked

有时候&#xff0c;Web服务器生成HTTP Response是无法在Header就确定消息大小的&#xff0c;这时一般来说服务器将不会提供Content-Length的头信息&#xff0c;而采用Chunked编码动态的提供body内容的长度。进行Chunked编码传输的HTTP Response会在消息头部设置&#xff1a;Tra…

【LeetCode】142 - Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Follow up:Can you solve it without using extra space? Solution&#xff1a; Discuss上的分析&#xff1a;Suppose the first meet at step k,the length of the Cycle …

3000 字详解 Pandas 数据查询,建议收藏

作者 | 俊欣来源 | 关于数据分析与可视化今天小编来和大家说一说怎么从DataFrame数据集中筛选符合指定条件的数据&#xff0c;希望会对读者朋友有所帮助。导入数据集和模块我们先导入pandas模块&#xff0c;并且读取数据&#xff0c;代码如下import pandas as pd df pd.read_c…

stylus使用文档总结:内置方法+参数+条件+迭代+导入+继承

一、内置方法 返回各种颜色的比重&#xff08;如red(color)等&#xff09; 颜色函数是CSS预处里器中内置的颜色函数功能&#xff0c;这些功能可以对颜色值进行处理&#xff0c;例如颜色的变亮、变暗、渐变颜色等处理十分的方便。 lighten(color, 10%); /* 返回的颜色在color基础…

用 Python 制作酷炫的可视化大屏,特简单!

作者 | 小F来源 | 法纳斯特在数据时代&#xff0c;我们每个人既是数据的生产者&#xff0c;也是数据的使用者&#xff0c;然而初次获取和存储的原始数据杂乱无章、信息冗余、价值较低。要想数据达到生动有趣、让人一目了然、豁然开朗的效果&#xff0c;就需要借助数据可视化。以…

HTTP协议中的Tranfer-Encoding:chunked编码解析

当不能预先确定报文体的长度时&#xff0c;不可能在头中包含Content-Length域来指明报文体长度&#xff0c;此时就需要通过Transfer-Encoding域来确定报文体长度。通常情况下&#xff0c;Transfer-Encoding域的值应当为chunked,表明采用chunked编码方式来进行报文体的传输。chu…

[转] splice系列系统调用

关注splice系列系统调用&#xff08;包括splice&#xff0c;tee和vmsplice&#xff09;已经有一段时间了&#xff0c;开始的时候并未能领会splice的意义所在&#xff0c;致使得出了“splice系列系统调用不怎么实用”的错误结论。随着内核研究的深入&#xff0c;才逐渐懂得&…

嵌入式s5vp210裸机 KXTF9-2050(G-sensor)

1.KXTF9-2050简介 KXTF9-205是G-sensor的一种&#xff0c;G-sensor&#xff08;Gravity sensor&#xff09;&#xff0c;重力传感器&#xff0c;又名加速度传感器&#xff08;accelerometer&#xff09;&#xff0c;是能感知加速度大小的MEMS(微机电系统)传感器。使用I2C协议和…