可重用、灵活的错误报告框架






3.04/5 (20投票s)
2004年4月29日
5分钟阅读

79780

975
通过使用配置类和简单的实现,该库允许您的应用程序以灵活的方式报告发生的错误。其中包括一个类似于 Windows XP 的 WinForms UI,允许用户选择在 WinForms 应用程序中报告错误。
引言
错误处理是任何开发人员或开发团队必须实现的更困难的任务之一。团队在如何处理应用程序中的异常方面面临各种挑战。通常,您会在设计的每个应用程序中“重新发明轮子”;因为许多人认为应用程序的规定决定了异常处理方法,所以您最终需要为开发的每个应用程序重新创建异常处理。
Microsoft 提供了其 Exception Application Block 来进行大量的异常管理,但对于许多应用程序场景,该块可能过于庞大。尽管它提供了许多灵活性,但设置和配置可能很麻烦,而且在很多情况下,比您正在开发的应用程序还要大!
本文将提出一种更简单的方法,并为您提供一个灵活的库,您可以使用它来处理自己的异常。ErrorTrapper
库完全包含在单个 .NET 程序集中,并且可以通过在 App.config 或 Web.config 文件中指定信息来相对灵活地使用。首先,将简要讨论 ErrorTrapper
的设计。然后,将使用 WinForms 技术提出一个示例场景,该场景将演示 ErrorTrapper
用途的相对基本实现。
首先 - IErrorReporter 接口
ErrorTrapper
库的主要组件——将为模型本身的设计带来灵活性的部分——是 IErrorTrapper
。下面,您可以看到提供此接口结构的 C# 代码
public interface IErrorReporter
{
bool ReportError(Exception exception);
}
实现此接口的类只需包含对单个方法 ReportError()
的实现。您自己的类可以使用 ErrorTrapper
库为应用程序提供任何所需的实现。稍后,我们将使用后期绑定和 Activator.CreateInstance()
方法来创建可以实现此功能的类型的实例。
本文提供的代码下载包含一个利用 ErrorTrapper
库的简单 WinForms 应用程序。此实现只是将处理过的异常的 ToString()
等效项写入磁盘上的文件。下面,您可以看到此类的代码,并对 ErrorTrapper
库在您自己的应用程序开发周期中的灵活性有所了解
public class CustomErrorTrapperExample : IErrorReporter
{
public bool ReportError(Exception exception)
{
try
{
string filename = @"C:\ExceptionLog.txt";
FileMode fm = FileMode.Append;
if(!File.Exists(filename))
{
fm = FileMode.Create;
}
StringBuilder sb = new StringBuilder();
FileStream fs = new FileStream(filename,fm);
sb.Append(DateTime.Now.ToString());
sb.Append(Environment.NewLine);
sb.Append("---------------------------------------------------------");
sb.Append(Environment.NewLine);
sb.Append(exception.ToString());
sb.Append(Environment.NewLine);
sb.Append("---------------------------------------------------------");
sb.Append(Environment.NewLine);
string s = sb.ToString();
Byte[] byt = Encoding.ASCII.GetBytes(s);
fs.Write(byt,0,byt.Length);
fs.Close();
return true;
}
catch
{
return false;
}
}
尽管这是一个相对简单的示例,但它演示了您如何在自己的应用程序范例中编写自定义实现,当应用程序“崩溃”时,ErrorTrapper
库将执行这些自定义实现。
那么我如何使其灵活呢?
这个问题的答案相对简单。使用 app.config 或 web.config 文件中的自定义配置节,您将提供一些信息来“驱动” ErrorTrapper
库的某些方面。正如您稍后将看到的,ErrorTrapper 具有用户界面方面。现在,让我们保存讨论,看看提供运行时信息的配置代码。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="ErrorTrapper"
type="System.Configuration.NameValueSectionHandler" />
</configSections>
<ErrorTrapper>
<add key="exceptionHandlerType"
value="ClientApplication.CustomErrorTrapperExample,
ClientApplication"/>
<add key="showUI" value="true"/>
<add key="uiLabel" value="Something Exploded!"/>
<add key="uiIntro"
value="We're sorry, but something has happened.
Would you like to report this explosion?"/>
</ErrorTrapper>
</configuration>
从这个配置节可以看出,我们将使用一个相对简单的范例来配置 ErrorTrapper
库。通过使用 NameValueSectionHandler
配置类,我们将提供 ErrorTrapper
在运行时需要使用的四个属性
exceptionHandlerType
(string
)showUI
(bool
)uiLabel
(string
)uiIntro
(string
)
这些属性中的第一个,exceptionHandlerType
,将是 Type
的名称,ErrorTrapper
将在运行时创建该类型来处理异常。有一个重要的注意事项——此区域中提供的 Type
必须实现 IErrorReporter
接口!如果它没有,运行时将抛出异常(想想看,这是有道理的!)。我们之前讨论过的具有简单实现的类——CustomErrorTrapperExample ——已在此示例中提供。
现在 - WinForms 界面!
Microsoft Windows 和一些支持的应用程序为我们提供了一项很棒的功能——能够将发生的错误发送到 Microsoft Web 服务,该服务会汇总其应用程序中发生的异常。您可能已经看到过当某些程序“崩溃”时偶尔弹出的对话框,为您提供了将错误报告给 Microsoft 的选项。
ErrorTrapper
库为您的 WinForms 应用程序提供了非常类似的功能——一个显示异常信息的 UI,带有“发送”和“不发送”按钮,用户可以根据需要使用。此实现显示的对话框如下
现在您已经有了参考,我们将继续检查最后三个配置元素。其中第一个是布尔属性 showUI
,可用于指定是否显示 UI。这样想:如果您想在 WebForms 应用程序中使用 ErrorTrapper
,显示此 UI 可能不是一个好主意。如果此值设置为 true
,用户可以选择将异常提交给您的自定义 IErrorReporter
实现。如果该值设置为 false
,您的实现将简单地执行。
接下来是 uiLabel
属性。在示例截图中,此值已设置为字符串“Something Exploded!”。简单来说,此元素/属性定义了对话框的 Text
属性,并在显示 WinForm 时显示在标题栏中。
最后是 uiIntro
属性。非常简单,这是显示给用户的文本,位于按钮上方。从这个例子可以看出,您不仅可以自定义当异常被 ErrorTrapper
库处理时发生的功能——您甚至可以自定义当异常在 WinForms 应用程序中被处理时显示给用户的对话框!完全灵活!
最后,使用 ErrorTrapper
我们将查看的最后一段代码来自示例下载。这个 WinForms UI 提供了两个会触发——或导致——简单异常的按钮。在应用程序执行开始时,我们将简单地处理 ThreadException
事件,并在事件处理程序中,将触发的异常发送到 ErrorTrapper
的执行周期。代码如下
static void Main()
{
Application.ThreadException += new
System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.Run(new Form1());
}
private static void Application_ThreadException(object sender,
System.Threading.ThreadExceptionEventArgs e)
{
ErrorHandler.HandleError(e.Exception);
}
private void btnSimpleError_Click(object sender, System.EventArgs e)
{
throw new Exception("This is a simple error");
}
private void btnDbFailure_Click(object sender, System.EventArgs e)
{
SqlConnection cn = new SqlConnection("this will break");
cn.Open();
}
就是这样!您拥有一个简单、灵活且完全可自定义的异常管理工具,配有一个类似 Windows XP 的用户界面,如果您希望向用户提供报告或不报告异常的选项,就可以向他们显示该界面!
祝您编码愉快!
注意 - 此程序集已为您进行了强命名和文档记录。因此,请随意将其放入 GAC 并根据需要使用!