zoukankan      html  css  js  c++  java
  • .NET:异常处理的两条“黄金定律”,求批!

    背景

    架构之处必须考虑:如何处理异常?如何定义自己的异常体系?本文为了强化这个概念而写。

    异常处理的两条“黄金定律”

    自己抄袭的两条规律:

    1. 异常不能穿过“边界类”。
    2. 异常不能在没有恢复的情况下“吞掉”。

    我们会将异常分为两类:“需要恢复”和“不需要恢复”,“需要恢复”的异常如果到达了边界类,就说明系统有BUG了,这类异常需要记录到日志。“不需要恢复”的异常需要进一步分为:“我们不能恢复”和“我们不期望恢复”,如果这类异常到达边界类,“我们不能恢复“的异常同样需要记录到日志,“我们不期望恢复”的异常则直接将异常信息显示给界面。一般采用AOP处理边界异常。

    示例

    AOP

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using System.Web.Mvc;
     7 
     8 using Common.Logging;
     9 using Happy.ExceptionHanding;
    10 using Happy.Web.Mvc.Newtonsoft;
    11 
    12 namespace Happy.Web.Mvc.ExceptionHanding
    13 {
    14     /// <summary>
    15     /// 处理应用程序未捕获的异常。
    16     /// </summary>
    17     [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
    18     public class WriteExceptionResultAttribute : FilterAttribute, IExceptionFilter
    19     {
    20         /// <inheritdoc />
    21         public void OnException(ExceptionContext filterContext)
    22         {
    23             var exception = filterContext.Exception;
    24             if (!FriendlyExceptionRegistry.IsFriendly(exception.GetType()))
    25             {
    26                 LogManager.GetCurrentClassLogger().Error(exception);
    27             }
    28             filterContext.Result = CreateErrorResult(exception);
    29             filterContext.ExceptionHandled = true;
    30         }
    31 
    32         private static ActionResult CreateErrorResult(Exception exception)
    33         {
    34             var information = ExceptionInformationProviderRegistry.CreateInformation(exception);
    35 
    36             return new NewtonsoftJsonResult
    37             {
    38                 Data = information
    39             };
    40         }
    41     }
    42 }
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 using Happy.ExtentionMethods;
     8 
     9 namespace Happy.ExceptionHanding
    10 {
    11     /// <summary>
    12     /// 异常信息提供者注册处。
    13     /// </summary>
    14     public static class ExceptionInformationProviderRegistry
    15     {
    16         private static readonly Dictionary<Type, IExceptionInformationProvider> _providers
    17             = new Dictionary<Type, IExceptionInformationProvider>();
    18 
    19         /// <summary>
    20         /// 注册提供者。
    21         /// </summary>
    22         public static void Register<TException>(IExceptionInformationProvider provider)
    23             where TException : Exception
    24         {
    25             Register(typeof(TException), provider);
    26         }
    27 
    28         /// <summary>
    29         /// 注册提供者。
    30         /// </summary>
    31         public static void Register(Type exceptionType, IExceptionInformationProvider provider)
    32         {
    33             exceptionType.MustNotNull("exceptionType");
    34             provider.MustNotNull("provider");
    35 
    36             _providers[exceptionType] = provider;
    37         }
    38 
    39         public static Dictionary<string, object> CreateInformation(Exception exception)
    40         {
    41             exception.MustNotNull("exception");
    42 
    43             var exceptionType = exception.GetType();
    44 
    45             var information = CreateDefaultInformation(exception);
    46 
    47             if (_providers.ContainsKey(exceptionType))
    48             {
    49                 var extInformation = _providers[exceptionType].CreateInformation(exception);
    50 
    51                 foreach (var item in extInformation.ToDictionary())
    52                 {
    53                     information[item.Key] = item.Value;
    54                 }
    55             }
    56             else
    57             {
    58                 if (FriendlyExceptionRegistry.IsFriendly(exception.GetType()))
    59                 {
    60                     information["exception"] = Resource.Messages.Msg_DefaultExceptionMessage;
    61                 }
    62             }
    63 
    64             return information;
    65         }
    66 
    67         private static Dictionary<string, object> CreateDefaultInformation(Exception exception)
    68         {
    69             return new Dictionary<string, object> 
    70             { 
    71                 { "success", false },
    72                 { "exception", exception.GetType().Name },
    73                 { "message",exception.Message }
    74             };
    75         }
    76     }
    77 }

    备注

    放弃继续玩 GO 的一个原因就是:GO 的异常处理太不爽了,或者是我自己的原因,不够 OPEN。

  • 相关阅读:
    深入浅出SQL Server 2008 分区函数和分区表
    数据库的恢复模式
    Windows Server 2003网络负载均衡的实现(转)
    SharePoint2010网站备份还原简单介绍
    HTTP协议详解(转)
    SharePoint 2010之LINQ与SPMetal
    moss 自定义文档库文档图标
    SharePoint 2010环境搭建
    C#中的yield关键字
    .NET开发中你可能会用到的常用方法总结(添加ing...)
  • 原文地址:https://www.cnblogs.com/happyframework/p/3381676.html
Copyright © 2011-2022 走看看