如何处理分层架构中的异常?

时间:2012-03-29 19:14:29

标签: exception exception-handling layer n-tier-architecture

在您离开谷歌之前,我已经阅读了很多关于异常处理的文章,帖子和评论,但我仍然坚持这些具体要点。

鉴于以下示例,您将如何处理以下情况?

  1. 如果DAL层中发生异常并且包含在自定义异常中以提供更多信息并更好地对其进行分类。我该如何登录?
  2. 如果我在DAL层中记录它,它将在全局处理程序中再次记录(使用elmah)。我可以让它传播,但是如果ServiceLayer需要将该异常转换为用户更友好的消息或者可能用于事务目的(想想回滚)会发生什么?我将丢失在DAL异常中收集的信息(无论如何消息,不一定是堆栈跟踪)。

     // UI
            public static GetUser(int userId)
            {
                // Should I do validation here or in service layer
                try
                {
                   IUserService s = new UserService(userId);
                   s.GetUser(userId);
                } 
                catch(ServiceLayerException ex)
                {
                    // ex.Message displayed to user
                }
    
            }
    
    
            // Service layer
            public User GetUser(int userId)
            {           
                try
                {
                    return repo.GetUser(userId);
                }
                catch(DALException ex)
                {
                    // user-friendly message displayed to user
                    throw new ServiceLayerException("User does not exist");
                }
            }
    
    
    
            // DAL
            public User GetUser(int userId)
            {
                try
                {
                    // Query for user, if fails throw DALException
                    return userId;
                }
                catch (SqlException ex)
                {
                    throw new DALException("Could not retrieve user with userId " + userId.ToString());
                }
    
            }
    

1 个答案:

答案 0 :(得分:1)

我个人更喜欢登录煤层 - 实际发生异常的地方,所以在第一种情况下我会登录DAL。如果我们不想传播错误,或者允许elmah记录错误,Bal(服务层)可以处理错误(这不是坏事,因为它将显示在错误页面上并帮助跟踪异常)。 服务层还可以将DAL错误作为内部异常传递,以便在需要时可以在访问期间/之后访问它 - 并且异常iteslf可以根据需要在层之间进行变更。用户通常不会想要这样的信息,只是收到通常的愚蠢消息。 也可以使用事件来收集异常数据(使用专门的事件争论)并且只返回布尔方法返回,这可以更加可控和可定制 - 尽管这会使你有责任传播或者不传播,这很可能仅用于“预期”例外。