今天工作中遇到了一个场景:前台调用后台通信接口时,如果出现错误会抛出异常。这里的异常信息格式为“[错误号] 错误信息”。现要针对指定的错误号做特殊处理。
处理逻辑需要放在主程序集中,因为处理需要用到的Application.Exit、Application.Restart只对主程序集起作用。而各业务系统的程序集都有可能调用前后台通信接口,所以我想了一个办法:在通信接口的所在的程序集拦截异常,如异常需要特殊处理,则触发相应事件由主程序集捕获并处理,否则直接抛出并由各业务系统自行处理。
为此我写了一个DEMO用于解决此问题,解决方案结构如下:
ExceptionFactory用于模拟触发异常的类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ExceptionMaker
{
public class ExceptionFactory
{
/// <summary>
/// 触发普通异常
/// </summary>
/// <param name="message">异常文本</param>
public static void MakeNormalException(string message)
{
try
{
//TODO:业务逻辑
throw new Exception(message);
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 触发特殊异常(含错误号)
/// </summary>
/// <param name="message">异常文本</param>
public static void MakeSpecialException(string message)
{
try
{
//TODO:业务逻辑
Exception ex = new Exception(message);
switch (message.Substring(0, 6))
{
case "[2016]":
{
if (Exception2016 != null)
{
Exception2016(ex);
}
}
break;
case "[2048]":
{
if (Exception2048 != null)
{
Exception2048(ex);
}
}
break;
}
throw ex;
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 特殊异常句柄
/// </summary>
/// <param name="ex"></param>
public delegate void KirovReportingHandle(Exception ex);
/// <summary>
/// 由错误号2016触发的事件
/// </summary>
public static event KirovReportingHandle Exception2016;
/// <summary>
/// 由错误号2048触发的事件
/// </summary>
public static event KirovReportingHandle Exception2048;
}
}
其中一共有两个函数:MakeNormalException和MakeSpecialException,前者用于模拟触发普通异常的情况,后者用于模拟触发带有错误号的异常的情况(即抛出的异常Message格式都为“[错误号] 错误信息”)。现指定2016、2048两个错误号是需要处理的,因此我们创建了两个事件Exception2016和Exception2048。
在主程序集中,程序界面如下:
程序代码如下(重点在Load函数,其中添加了对指定错误号异常进行拦截后的特殊处理):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ExceptionMaker;
namespace ExceptionTest
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
/// <summary>
/// Load函数:设定特殊异常的处理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormMain_Load(object sender, EventArgs e)
{
ExceptionFactory.Exception2016 += (ex) =>
{
MessageBox.Show("触发了异常:2016,程序即将重启");
Application.Restart();
};
ExceptionFactory.Exception2048 += (ex) =>
{
MessageBox.Show("触发了异常:2048,程序即将关闭");
Application.Exit();
};
}
/// <summary>
/// 触发普通异常
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnNormalException_Click(object sender, EventArgs e)
{
try
{
ExceptionFactory.MakeNormalException("Normal Exception");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
/// <summary>
/// 触发有错误号的异常
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSpecialException_Click(object sender, EventArgs e)
{
try
{
ExceptionFactory.MakeSpecialException("[1024] Special Exception");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
/// <summary>
/// 触发有错误号的异常 - 捕获后重启程序
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSpecialExceptionRestart_Click(object sender, EventArgs e)
{
try
{
ExceptionFactory.MakeSpecialException("[2016] Special Exception - PROGRAM RESTART");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
/// <summary>
/// 触发有错误号的异常 - 捕获后关闭程序
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSpecialExceptionClose_Click(object sender, EventArgs e)
{
try
{
ExceptionFactory.MakeSpecialException("[2048] Special Exception - PROGRAM CLOSE");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
END