как: обрабатывать исключения, лучшие практики - PullRequest
3 голосов
/ 29 мая 2010

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

У меня есть этот код:

public bool IsUserAuthorizedToSignIn(string userEMailAddress, string userPassword)
        {
            // get MD5 hash for use in the LINQ query
            string passwordSaltedHash = this.PasswordSaltedHash(userEMailAddress, userPassword);

            // check for email / password / validity
            using (UserManagementDataContext context = new UserManagementDataContext())
            {
                var users = from u in context.Users
                            where u.UserEMailAdresses.Any(e => e.EMailAddress == userEMailAddress)
                                && u.UserPasswords.Any(p => p.PasswordSaltedHash == passwordSaltedHash)
                                && u.IsActive == true
                            select u;

                // true if user found
                return (users.Count() == 1) ? true : false;
            }
        }

, а также md5:

private string PasswordSaltedHash(string userEMailAddress, string userPassword)
        {
            MD5 hasher = MD5.Create();
            byte[] data = hasher.ComputeHash(Encoding.Default.GetBytes(userPassword + userEMailAddress));

            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                stringBuilder.Append(data[i].ToString("x2"));
            }

            Trace.WriteLine(String.Empty);
            Trace.WriteLine("hash: " + stringBuilder.ToString());
            return stringBuilder.ToString();
        }

Итак, как мне поступить с обработкой исключений из этих функций? первый из них вызывается со страницы Default.aspx. вторая вызывается только из других функций из библиотеки классов.

Какая лучшая практика?

  • код окружения ВНУТРИ каждой функции с помощью try-catch
  • окружить ФУНКЦИОНАЛЬНЫЙ ЗВОНОК try-catch
  • что-то еще ??

что делать, если случаются исключения?

в этом примере: это вход пользователя в систему, поэтому каким-то образом, даже если все не удается, пользователь должен получить некоторую значимую информацию в виде строк: войти в систему в порядке (просто перенаправить), войти не в порядке (неправильное имя пользователя / пароль), войти не возможно из-за внутренних проблем, извините (исключение произошло).

для первой функции я беспокоюсь, если есть проблема с доступом к базе данных. не уверен, есть ли что-то, что нужно обработать во втором.

Спасибо за информацию. как бы ты это сделал? нужна конкретная информация по этому вопросу (для меня легче понять), а также общая информация о том, как выполнять другие задачи / функции.

Я посмотрел в Интернете, но у всех есть разные вещи, чтобы сказать, поэтому неуверенный, что делать ... пойдет или с большинством голосов здесь, или с наиболее логичным объясненным ответом :) спасибо.

Ответы [ 3 ]

4 голосов
/ 29 мая 2010

Два золотых правила:

  1. Создайте исключение, если метод не может делать то, что его имя говорит.
  2. Не перехватывайте исключения, если вы точно не знаете, что с ними делать.

Помните, что исключение указывает, что что-то пошло не так, и это что-то конкретное может не соответствовать вашему мнению. (Недостаточно памяти, переполнение стека, сбой сторонней службы, неудачное развертывание, что приводит к отсутствию сборок, неправильной конфигурации, исключениям безопасности и т. Д.).

За очень немногими исключениями, единственное место, где вы должны увидеть обработку исключений Pokemon, находится на самом верхнем уровне вашего кода, где исключение должно быть где-то опубликовано. Например, в методе Application_Error в вашем файле global.asax.

Вот несколько ссылок, которые могут оказаться для вас полезными:

3 голосов
/ 29 мая 2010

Вам нужно подумать о контрактах, которые определяют методы. Если метод не может выполнить свой контракт, вам нужно исключение. Исключения, сгенерированные в методе, должны быть преобразованы в исключения, которые имеют смысл с точки зрения контракта метода.

В первом случае я бы поймал любые исключения, которые могут быть сгенерированы при выполнении оператора (например, ошибки базы данных), и преобразовал бы их в нечто вроде AuthorisationException. Разрешать распространение исключения прямо вверх не имеет смысла с точки зрения контракта методов. Например, не имеет смысла позволять исключению базы данных выходить из метода, когда метод выполняет соглашение о том, авторизован ли автор.

Использование этой идеи метода в качестве контракта позволяет принимать правильные решения. Если контракт метода входит в базу данных или какие-то манипуляции с базой данных, вполне может иметь смысл распространять исключения.

Конкретизируем: Используя первый пример:

public bool IsUserAuthorizedToSignIn(string userEMailAddress, string userPassword)
    {
        try
        {
            // get MD5 hash for use in the LINQ query
            string passwordSaltedHash = this.PasswordSaltedHash(userEMailAddress, userPassword);

            // check for email / password / validity
            using (UserManagementDataContext context = new UserManagementDataContext())
            {
                var users = from u in context.Users
                        where u.UserEMailAdresses.Any(e => e.EMailAddress == userEMailAddress)
                            && u.UserPasswords.Any(p => p.PasswordSaltedHash == passwordSaltedHash)
                            && u.IsActive == true
                        select u;

                // true if user found
                return (users.Count() == 1) ? true : false;
            }
        }
        catch(ThisException e)
        {
            thrown new AuthorisationException("Problem1 occurred");
        }
        catch(ThatException e)
        {
            thrown new AuthorisationException("Problem2 occurred");
        }
        catch(OtherException e)
        {
            thrown new AuthorisationException("Problem3 occurred");
        }
    }

Вы также можете установить внутреннее исключение в AuthorisationException:

        catch(ThisException e)
        {
            thrown new AuthorisationException("Problem1 occurred", e);
        }

Тогда ваш клиентский код может сделать это:

try
{
    if(User.IsUserAuthorizedToSignIn)
    {
        // Let the magic happen
    }
    else
    {
        // No rights
    }
}
catch(AuthorisationException e)
{
    // Let the user know there is something up with the system. 
}

Вы можете решить, что не хотите перехватывать исключение AuthorisationException на сайте непосредственного вызова, поскольку не можете уведомить пользователя. Так что вы можете позволить ему распространяться до уровня, на котором вы можете что-то с ним сделать.

Надеюсь, это поможет!

3 голосов
/ 29 мая 2010

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

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

Если на вашем уровне представления приложений вы используете библиотечный код и знаете о возможных исключениях, то поймайте их с помощью try / catch.

Поскольку вы используете asp.net, я бы рекомендовал написать общий базовый класс страницы и поработать с некоторым механизмом обработки ошибок в событии Page_Error, которое перехватывает все необработанные исключения на странице.

Более того, вы можете использовать Application_Error даже в global.asax, чтобы перехватывать любые необработанные исключения в любой части приложения, модулях, обработчиках, сервисах, страницах и т. Д.

Я бы настоятельно рекомендовал не делать этого общая практика, чтобы справиться со всеми исключение в глобальной Application_Error.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...