在我的WebApi 2项目中,我遵循服务模式以及工作单元和通用存储库模式。
所有控制器都有try-catch
,如果某个操作没有,我有一个全局IAutofacExceptionFilter
会捕获未处理的异常。
服务层也有异常处理。但是,存储库没有异常处理,因此异常会冒泡到他们遇到的第一个try-catch
。
我还有一个自定义DatabaseException
类,用于捕获SaveChanges
上抛出的EF的数据库异常,这样可以正常工作。
但是,由于项目目前正处于大量开发阶段,数据库更改与代码更改相同,因此SQLException
或EntityCommandExecutionException
等异常非常常见。我想抓住这些异常并抛出我自己的DatabaseException
。
我是否应该在存储库级别,服务级别或控制器级别捕获这些异常?
答案 0 :(得分:1)
直接回答你的问题 - 我会在服务级别捕获异常,记录它们,然后重新抛出它们。
现在异常被重新抛出,应用程序也可以处理它,甚至再次记录它 - 这次是在调用控制器动作的上下文中。但是,例如,如果用户试图保存一些数据并且它失败了,那么在该上下文中它失败的原因可能并不重要。因此,捕获特定的异常类型可能不会有帮助。 (可能。)
如果应用程序要采取一些不同的操作来处理或解决异常,那么捕获特定类型的异常只会非常有用,这种情况并不常见。能够轻松访问日志并查找异常,任何异常都比将系统异常转换为自定义异常更有价值。
答案 1 :(得分:0)
通常我的MVC应用程序中没有try_catchs(不包括一个或两个现有的try catchs)
我的所有控制器都继承自BaseController
我有一个属性,可以捕获我的应用程序中的所有异常:
public class HandleExceptionsAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
filterContext.Exception.InsertIntoDB(Membership.CurrentUserId, filterContext.RouteData.Values["controller"].ToString(), filterContext.RouteData.Values["action"].ToString());
}
}
[HandleExceptionsAttribute(View = "/Error/Index")]
public class BaseController : Controller
{
// Code...
}
在HandleErrorAttribute
中,如果发生错误,您甚至可以选择要显示的页面。
如果您想过滤特定的例外:
if (filterContext.Exception is EntityCommandExecutionException)
// code
注意强>
要查看发生异常的操作和控制器,我获取当前控制器和当前操作并将其插入数据库。