Как реализовать обработку ошибок [закрыто]

13

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

За моей обработкой ошибок нет структуры. Я хотел бы узнать и понять, как это реализовано на профессиональном уровне. Это одна из областей, где мне не хватает знаний.

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

Я кодирую в основном на C #.

Джеймс Джеффри
источник
2
Зачем голосовать? Я задаю серьезный вопрос о реализации обработки ошибок и о том, как это делается. Если это не лучшее место, чтобы задать такой вопрос среди программистов, тогда где? Меня действительно беспокоит, когда люди голосуют против таких вопросов, потому что больше некуда задавать такой вопрос. Возможно, это единственное место в Интернете, где я собираюсь получить надежный ответ и возможные ресурсы. Таким образом, вместо того, чтобы отказаться от голосования на вопрос, что другие люди наверняка будут Google, не будет ли проще ответить на него?
Джеймс Джеффри
6
Ваш вопрос очень широкий. Возможно, вы могли бы сузить область применения, приведя конкретные примеры того, как вы не смогли достичь своих целей кодирования.
Andyz Smith
В Интернете есть много статей об обработке ошибок: Попробуйте это: msdn.microsoft.com/en-us/library/seyhszts.aspx
Нир Корнфельд,

Ответы:

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

  2. Не используйте исключения для обработки неправильного кода. Чтобы проверить правильность кода, вы должны использовать либо утверждения, либо, в .NET Framework 4 и более поздних версиях, контракты Code (которые заменяют утверждения и имеют дополнительные, особенно ценные функции).

  3. Не используйте исключения в неисключительных случаях. Тот факт, что пользователь, когда его попросили ввести число, ввел «собаку», не так уж и исключителен, чтобы заслуживать исключения.

  4. Будьте осторожны при выборе типов исключений. Создавайте свои собственные типы при необходимости. Тщательно выбирайте наследство, помня, что ловящие родители будут ловить и детей. Никогда throw Exception.

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

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

    // Note that the operation fails pretty often, since it deals with the servers which are
    // frequently unavailable, and the ones which send garbage instead of the actual data.
    private LoadOperationResult LoadProductsFromWeb()
    {
        ...
    }

    Смысл LoadOperationResult.ServerUnavailable, LoadOperationResult.ParsingErrorи т.д. гораздо более четко , чем, скажем, помня , что код 12 означает , что сервер отключен, а код 13 - что данные не могут быть разобраны.

  7. Используйте коды ошибок, когда они ссылаются на общие, известные каждому разработчику, работающему в определенной области. Например, не изобретайте заново значение перечисления для HTTP 404 Not Found или HTTP 500 Internal Server Error.

  8. Остерегайтесь логических значений. Рано или поздно вам захочется узнать не только, был ли конкретный метод успешным или неудачным, но и почему. Исключения и перечисления намного более сильны для этого.

  9. Не перехватывайте каждое исключение (если только вы не на самом верху стека). Если вы поймали исключение, вы должны быть готовы к нему. Поймать все показывает, что вам все равно, если ваш код работает правильно. Это может решить «Я не хочу сейчас искать, как это исправить», но рано или поздно нанесет вам вред.

  10. В C # никогда не перебрасывайте исключения как это:

    catch (SomeException ex)
    {
        ...
        throw ex;
    }

    потому что ты разбиваешь стек Сделайте это вместо этого:

    catch (SomeException)
    {
        ...
        throw;
    }
  11. Приложите усилия при написании сообщений об исключениях. Сколько раз я видел что-то вроде throw Exception("wrong data")или throw Exception("shouldn't call this method in this context"). Другие разработчики, включая вас самих шесть месяцев спустя, не будут знать, какие данные неверны и почему или почему мы не должны вызывать какой-либо метод в контексте или какой именно контекст.

  12. Не показывать сообщения об исключениях для пользователя. Они не ожидаются для обычных людей, и часто даже нечитаемы для самих разработчиков.

  13. Не локализуйте сообщения об исключениях. Поиск документации для локализованного сообщения является изнурительным и бессмысленным: каждое сообщение должно быть только на английском и английском языках.

  14. Не сосредотачивайтесь исключительно на исключениях и ошибках: журналы также чрезвычайно важны.

  15. В .NET не забудьте включить исключения в документацию XML метода:

    /// <exception cref="MyException">Description of the exception</exception>

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

    В этом смысле обработка Java-исключений обеспечивает более строгий и лучший подход. Это заставляет вас либо иметь дело с исключениями, которые могут быть вызваны вызванными методами, либо объявить в вашем собственном методе, что он может генерировать исключения, которые вы не обрабатываете, делая вещи особенно прозрачными.


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

оборота МайнМа
источник
Я узнал цитату немного из этого, могу я спросить, откуда появился этот список? Сайт или личный опыт? В любом случае исключительная работа (хе-хе получить его?).
Shelby115 9.09.13
@ Shelby115: список составлен по порядку: обмен стеками, личный опыт и код завершения Стивом Макконнеллом.
Арсений Мурзенко
Спасибо @MainMa, это отличный ответ! Я имел обыкновение владеть Code Complete, когда я учился в университете, но кто-то украл его. Я не смог прочитать это.
Джеймс Джеффри
@JamesJeffery: затем одолжите второе издание в библиотеке или купите одно: это одна из редких книг, связанных с развитием, которая полностью стоит денег.
Арсений Мурзенко
@MainMa Только что заказал у Амазонки, спасибо: я тоже владею Чистым Кодом и полностью забыл о Главе 7.
Джеймс Джеффри
1

Я думаю, что список MainMa очень полон. Я просто добавлю несколько своих:

  1. Прочитайте статью Эрика Липперта о том, как он классифицирует исключения. Особенно важно, чтобы он не улавливал исключения, которые в действительности являются ошибками в вашем коде. Исправьте код вместо этого!
  2. Если вы знаете, что может возникнуть исключение, и вы можете что-то с ним сделать, обработайте его, но ограничьте область действия своего try-catch и перехватите конкретное исключение, которое вы ожидаете. То есть не делайте этого:

public void Foo() {
    try {
        //get input from use
        //do calculations
        //open file
    }
    catch (Exception ex) {
       //handle exception
    }
}

Вместо этого сделайте это:

public void Foo() {
    //get input from use
    //do calculations
    try {
        //open file
    }
    catch (FileOpenException ex) {
       //handle exception
    }
}
  • Не используйте исключения для потока управления. Например, не выбрасывайте исключение ClientNotFoundException в диалоговом окне поиска (клиент не найден не является исключительным в этой ситуации) и ожидайте, что вызывающий код покажет сообщение «Результаты не найдены», когда это произойдет.

  • Не глотайте исключения!

  • Имейте в виду, что действительно обработка исключения может означать только 3 вещи:

    1. Повторите операцию. Действителен только если проблема временная.
    2. Попробуйте альтернативу.
    3. Сообщите кому-нибудь о проблеме. Действителен только в том случае, если уведомление является действующим, что означает, что пользователь может что-то с этим сделать.

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

Майк
источник