在控制器级别捕获SqlException?

问题描述 投票:0回答:2

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

所有控制器都有

try-catch
,以防万一某个操作没有,我有一个全局
IAutofacExceptionFilter
将捕获未处理的异常。

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

try-catch

我还有一个自定义

DatabaseException
类,可以捕获
SaveChanges
上引发的 EF 数据库异常,并且效果很好。

但是,由于该项目目前正在大力开发,数据库更改与代码更改同时发生,因此诸如

SQLException
EntityCommandExecutionException
之类的异常情况很常见。我想捕获这些异常并抛出我自己的
DatabaseException

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

c# .net entity-framework asp.net-web-api
2个回答
1
投票

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

  • 从数据库检索数据是服务的一项功能,因此如果该功能失败,则说明服务失败。
  • 应用程序不“了解”数据库。它不从数据库获取数据。它从服务获取数据。它不应该依赖于服务中的实现细节,例如数据是否来自 SQL 还是其他地方。

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

只有当应用程序要采取一些不同的操作来处理或解决异常时,捕获特定类型的异常才有真正的帮助,而这种情况并不常见。能够轻松访问日志并找到异常(任何异常)比将系统异常转换为自定义异常更有价值。


0
投票

通常我的 MVC 应用程序中没有 try_catchs(不包括一两个现有的 try catch)

我所有的控制器都是继承自

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

注意

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

© www.soinside.com 2019 - 2024. All rights reserved.