优雅的处理异常
最近几年在做项目过程中发现项目中出现的问题,一部分由于项目前期一些很基础的技术系统没有注意, 所以总结了项目开始搭建架构的时候应该注意的技术问题和技术框架的选型。
所有所谓的最佳实践只是参考,本文也不例外。
异常处理是程序最基本的问题,我见过最多的处理异常的方式,在业务层一个大的try catch):
public static Customer GetCustomer(string account, string password) { try { using (IDbConnection dbConnection = ConnectionFactory.CreateConnection()) { string sql = "select * from Customer where Account=@account and Password=@password and IsDisabled=0"; return dbConnection.Query<Customer>(sql, new { account, password }).FirstOrDefault(); } } catch(Exception ex) { LogHelper.Current.Error("Application_Error", exception); return null; } }
所有的业务逻辑都包裹一层try..catch ,这种方式有俩种坏处:
1.程序异常后应向上抛出业务层请应自动终止,而不是继续执行,继续执行会造成脏数据。
2.忘记try catch就无法捕获异常,线上环境找不到问题所在。
3.每次上层调用都需要加if(var==null)判断,每次都得想着真浪费时间。
比较好的方式应去除显示try catch代码,异常由Application_Error统一处理(如果异常后业务需要重试操作例外),需注意以下几点:
1.增加处理开关,如果是本地环境无需处理异常,直接报黄页,这样方便调试错误(Request.IsLocal可以判断是否是本地请求)。
2.如果404的异常,不用处理。
3.记录完成异常后,需将请求导向错误页面。
protected void Application_Error(Object sender, EventArgs e) { if (Environment.IsLocal()) { return; } var exception = Server.GetLastError(); //不处理404异常 var httpException = exception as HttpException; if (httpException != null && httpException.GetHttpCode() == 404) { return; } if (exception != null) { LogHelper.Current.Error("Application_Error", exception); //导向错误页面 Response.Clear(); Response.StatusCode = 500; Response.Write("系统出现了异常,请重试"); Response.End(); } }