架构之处必须考虑:如何处理异常?如何定义本身的异常体系?本文为了强化这个概念而写。架构
本身抄袭的两条规律:app
咱们会将异常分为两类:“须要恢复”和“不须要恢复”,“须要恢复”的异常若是到达了边界类,就说明系统有BUG了,这类异常须要记录到日志。“不须要恢复”的异常须要进一步分为:“咱们不能恢复”和“咱们不指望恢复”,若是这类异常到达边界类,“咱们不能恢复“的异常一样须要记录到日志,“咱们不指望恢复”的异常则直接将异常信息显示给界面。通常采用AOP处理边界异常。ide
AOPspa
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。日志