10

我在我的应用程序中遵循了这种处理异常的方式。但是我的领导说我做错了。我只是包装并重新抛出相同的异常,这会影响性能。

我的方法有什么问题?有人对我如何在这里记录和处理异常有任何建议吗?

public class BusinessRepository : IBusinessRepo
{
    public List<Employee> GetEmployees()
    {
        try
        {
            //do some DB operations
        }
        catch (SQLException sqlex)
        {
            Logger.Log("Exception detail with full stack trace");
            throw new DALException(sqlex, "Error in data access layer");
        }

    }
}
public class BusinessLayerClass : IBusinessLayer
{
    private readonly IBusinessRepo Repo;
    public BusinessLayerClass(IBusinessRepo rep)
    {
        Repo = rep;
    }
    public List<Employee> GetEmployees()
    {
        try
        {
           List<Employee> emps= return Repo.GetEmployees();
        }
        catch (DALException dex)
        {
            //do nothin as it got already logged
            throw;
        }
        catch (Exception ex)
        {
            Logger.Log(ex, "Business layer ex");
            throw new BusinessLayerEx(ex);
        }
    }
}

public class HomeController : Controller
{
    public ActionResult Index()
    {
        try
        {
            List < Employee >= BusinessLayerClass.GetEmployees();

        }
        catch (DALException)
        {
            //show error msg to user
        }
        catch (BusinessLayerEx)
        {
            //show error msg to user
        }
        catch (Exception ex)
        {
            Logger.Log();
            //show error msg to user
        }
        return View(emps);
    }
 }

我是否遵循上面显示的正确的冒泡、处理和记录方式?

4

4 回答 4

3

只要满足两个条件,我倾向于同意你这样做的方式:

  1. 您的Logger.Log语句记录的内容比您在此处指出的更有意义/有用(我猜您的代码在这里只是一条指示错误已记录的示例消息)。如果它提供了可用于追踪异常原因的信息,那很好。
  2. 您的//show error msg to user评论意味着在该位置,您呈现一个很好的视图来解释发生了错误,并且您不只是显示默认的异常屏幕/轨迹跟踪。

至于您throw;何时捕获刚刚抛出的 DALException:没关系。您在这里的目标似乎是捕获来自前一层的任何异常并记录它,然后抛出您自己的异常。因为只有当你已经记录了另一个错误并自己抛出它时才会抛出 DALException,所以让它冒泡超过这个级别是完全可以的。

于 2013-01-15T18:20:05.910 回答
1

异常的一般经验法则是不要捕获它们,除非你可以“做点什么”,即增加价值。理想情况下,这将是某种优雅的恢复,直到用户永远不知道有打嗝,但至少这将包括记录异常——你正在做的。

不要捕获异常只是为了立即重新抛出它。那没有任何价值。(如果您需要将异常类型更改为更具信息性/更适合上下文的内容,则可能是一个例外)。

于 2013-01-15T18:25:51.730 回答
1

与任何正常的返回机制相比,抛出和捕获异常都是昂贵的,但这有点不重要——我们不应该将异常用作正常的控制流机制,而是用来处理异常的事情。

异常处理在技术上可能非常具有挑战性。毕竟,大多数时候我们完全没想到它们。但是,当团队或项目根本没有任何类型的错误处理策略时,几乎不可能“正确”处理异常。在一个理想的世界里,我们会在一开始就确切地知道我们需要处理什么样的错误条件,并且我们会在设计整个应用程序时考虑到这些情况(以及我们还需要记住的大量其他约束,从代码可读性到性能)。

我会说,如果您的领导说“这是错误的”,那么问“我们的错误处理策略是什么?”是公平的。如果你甚至不知道你的代码应该实现什么目的,你怎么可能交付出色的代码?

于 2013-01-15T18:44:59.103 回答
0

您的方法没有任何问题,但我认为您的自定义异常没有增加太多价值。在 DAL 中包装异常如何增加价值的一个示例是,如果您将特定的 SQL 异常(例如唯一键冲突)包装在自定义异常中,以便您的 UI 可以显示有意义的错误消息。

至于性能,无论如何都无关紧要,因为已经发生了非常糟糕的事情。

于 2013-01-15T19:34:08.487 回答