在控制器级别捕获SqlException?

时间:2016-03-30 11:34:28

标签: c# entity-framework asp.net-web-api

在我的WebApi 2项目中,我遵循服务模式以及工作单元和通用存储库模式。

所有控制器都有try-catch,如果某个操作没有,我有一个全局IAutofacExceptionFilter会捕获未处理的异常。

服务层也有异常处理。但是,存储库没有异常处理,因此异常会冒泡到他们遇到的第一个try-catch

我还有一个自定义DatabaseException类,用于捕获SaveChanges上抛出的EF的数据库异常,这样可以正常工作。

但是,由于项目目前正处于大量开发阶段,数据库更改与代码更改相同,因此SQLExceptionEntityCommandExecutionException等异常非常常见。我想抓住这些异常并抛出我自己的DatabaseException

我是否应该在存储库级别,服务级别或控制器级别捕获这些异常?

2 个答案:

答案 0 :(得分:1)

直接回答你的问题 - 我会在服务级别捕获异常,记录它们,然后重新抛出它们。

  • 从数据库中检索数据是服务的一项功能,因此如果失败,则服务失败。
  • 申请表没有"知道"关于数据库。它没有从数据库中获取数据。它从服务中获取数据。它不应该依赖于服务中的实现细节,例如数据是来自SQL还是来自其他地方。

现在异常被重新抛出,应用程序也可以处理它,甚至再次记录它 - 这次是在调用控制器动作的上下文中。但是,例如,如果用户试图保存一些数据并且它失败了,那么在该上下文中它失败的原因可能并不重要。因此,捕获特定的异常类型可能不会有帮助。 (可能。)

如果应用程序要采取一些不同的操作来处理或解决异常,那么捕获特定类型的异常只会非常有用,这种情况并不常见。能够轻松访问日志并查找异常,任何异常都比将系统异常转换为自定义异常更有价值。

答案 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

注意

要查看发生异常的操作和控制器,我获取当前控制器和当前操作并将其插入数据库。