Как обрабатывать исключения в многоуровневой архитектуре? - PullRequest
1 голос
/ 29 марта 2012

Прежде чем вы убежите и погуглите, я прочитал множество статей, постов и комментариев по обработке исключений, но я все еще застрял в этих конкретных моментах.

Учитывая приведенный ниже пример, как бы вы справились со следующими сценариями?

  1. Если исключение возникает на уровне DAL и заключено в пользовательское исключение, чтобы предоставить больше информации и лучше классифицировать ее. Как мне войти?

Если я запишу его так, как это происходит на уровне 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 Ответ

1 голос
/ 29 марта 2012

Лично я предпочитаю Войти на Coalface - где на самом деле произошло исключение, поэтому в первом случае я бы войти в DAL. Bal (Service Layer) может обработать ошибку, если мы не хотим распространять ошибку, или разрешить elmah регистрировать ее (что неплохо, так как это отобразится на странице ошибок и поможет в отслеживании исключения). Служебный уровень также может передавать ошибку DAL как внутреннее исключение, чтобы он был доступен во время / после распространения, если требуется, и исключение iteslf может быть изменено по мере необходимости между уровнями. Пользователь, как правило, не хочет такой информации, а просто получает обычное тупое сообщение. Также возможно использовать события для сбора данных об исключениях (со специализированными аргументами событий) и просто передавать обратно булевы методы, это может быть более управляемым и настраиваемым - хотя это затем возлагает на вас ответственность за распространение или нет, и это вероятно использоваться только для «ожидаемых» исключений.

...