错误处理我应该抛出异常吗?或者在源头处理?

cho*_*bo2 13 c# asp.net-mvc exception-handling

我有这种格式

asp.net MVC视图 - >服务层 - >存储库.

因此视图调用服务层,该服务层中包含业务/验证逻辑,而后者又调用存储库.

现在我的服务层方法通常有一个bool返回类型,所以如果数据库查询已经完成,我可以返回true.或者如果失败了.然后向用户显示通用消息.

我当然会用elmah记录错误.但是我不确定我应该怎么做到这一点.

就像现在我的Repository有更新,创建,删除的void返回类型.

所以说如果更新失败,我应该在我的存储库中有一个try/catch引发错误,然后我的服务层捕获它并执行elmah信令并返回false?

或者我应该让这些存储库方法返回"bool",尝试/捕获存储库中的错误,然后将"true"或"false"返回到服务层,然后又向视图返回"true"或"false"?

异常处理仍然让我感到困惑的是如何处理错误以及何时抛出以及何时捕获错误.

小智 22

我经常使用的经验法则是:

  • 在低水平时,由于特殊情况而无法完成操作时抛出.
  • 在中间层中,捕获多个异常类型并重新包装在一个异常类型中.
  • 在最后一个负责任的时刻处理异常.
  • 文献!

以下是多层ASP.NET MVC应用程序(UI,Controller,Logic,Security,Repository)的伪代码示例:

  1. 用户点击提交按钮.
  2. 执行控制器操作并调用逻辑(业务)层.
  3. 逻辑方法使用当前用户凭据调用Security
    • 用户无效
      • 安全层抛出SecurityException
      • 逻辑层捕获,在LogicException中包含更通用的错误消息
      • Controller捕获LogicException,重定向到Error页面.
    • 用户有效且安全性返回
  4. 逻辑层调用存储库以完成操作
    • 存储库失败
      • 存储库抛出RepositoryException
      • 逻辑层捕获,在LogicException中包含更通用的错误消息
      • Controller捕获LogicException,重定向到Error页面.
    • 存储库成功
  5. 逻辑层返回
  6. Controller重定向到Success视图.

注意,Logic层只抛出一个异常类型 - LogicException.冒泡的任何低级异常都会被捕获,包含在抛出的LogicException的新实例中.这给了我们很多好处.

首先,可以访问堆栈跟踪.其次,调用者只需要处理单个异常类型而不是多个异常.第三,可以按摩技术异常消息以显示给用户,同时仍保留原始异常消息.最后,只有负责处理用户输入的代码才能真正知道用户的意图是什么,并确定操作失败时的适当响应.存储库不知道UI是否应显示错误页面或请求用户使用不同的值再次尝试.控制器知道这一点.


顺便说一句,没有什么说你不能这样做:

try
{
  var result = DoSomethingOhMyWhatIsTheReturnType();
}
catch(LogicException e)
{
  if(e.InnerException is SqlException)
  {
    // handle sql exceptions
  }else if(e.InnerException is InvalidCastException)
  {
    // handle cast exceptions
  }
  // blah blah blah
}
Run Code Online (Sandbox Code Playgroud)