что не так с e.printStackTrace () для неизвестного исключения - PullRequest
9 голосов
/ 02 мая 2011

Если я использую регистратор в случае известных исключений, что не так с e.printStackTrace() для неизвестного исключения?

Мне всегда говорят не делать этого - но не дают причины

пример ниже

try {
            dostuff();
        } catch (AException ae) {
            logger.error("ae happened");
        } catch (BException be) {
            logger.error("be happened");
        } catch (CException ce) {
            logger.error("ce happened");
        } catch (Exception e) {
            e.printStackTrace();
        }

Ответы [ 6 ]

14 голосов
/ 02 мая 2011

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

edit: почему запись непосредственно в stderr имеетчего следует избегать?

В ответ на ваш вопрос, @shinynewbike, я немного изменил свой ответ.Чего следует избегать, так это писать напрямую в stderr без использования возможности logger.

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

Когда вы пишете напрямую в System.err или System.out, вы теряете эти функции, и что еще хуже, если вы смешаете logger и System.err.write, вы можете в конечном итоге получить трассировки в разных «файлах», что приведет к отладкеВаша система сложна.

5 голосов
/ 02 мая 2011

ИМХО, Вы должны

  • последовательно регистрировать в логгере ИЛИ стандартную ошибку, но не смешивать (возможно, это причина жалобы)
  • всегда регистрировать исключение страссировка стека, если вы не уверены, что она вам никогда не понадобится.
2 голосов
/ 05 августа 2011

Это плохо, потому что e.printStackTrace() не обязательно будет записывать в тот же файл журнала, что и logger.error(), поэтому для согласованности вы должны использовать logger.error() для всего.

Также e.printStackTrace() ничего не делает для описания того, что происходило, что вызвало ошибку. Вы должны всегда включать сообщение журнала, которое сделает это понятным человеку, который читает файл журнала.

Если вы отправите объект исключения в качестве второго параметра, и вы получите трассировку стека в файле журнала, а также строку сообщения об исключении. Бедная душа, читающая файл журнала, будет рада получить эту информацию.

try {
    doStuff();
}
catch (AException ae) {

    // Send to the log file a message describing what we were doing,
    // and what happened as a result

    logger.error("ae happened, while attempting to do stuff, but that's okay", ae);

    dealWithTheSituation();
}
catch (Exception e) {

    logger.fatal("an unexpected error happened, while attempting to do stuff, cannot proceed", e);

    abortAndCatchFire();  // Burn the evidence
}
2 голосов
/ 02 мая 2011

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

Самым распространенным сценарием является то, что ваше приложение работает внутри другого контейнера, такого как tomcat, который может выводить свои собственные сообщения в стандартный формат. Поскольку ваше приложение выполняется в одном и том же процессе, все ваши сообщения будут смешаны с контейнером вместе с сообщениями любого другого приложения, работающими в том же контейнере.

Использование библиотеки журналов дает вашему приложению возможность регистрировать сообщения в нескольких различных местах назначения, которые могут быть настроены программой развертывания. Вы не получите эту выгоду, когда используете e.printStackTrace().

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

  • Когда это нормально для catch(Exception ex)?
  • Когда и как должны регистрироваться исключения?
1 голос
/ 02 мая 2011

catch (Exception e) перехватывает все исключения, даже непроверенные, которые извлекаются из RuntimeException, например NullPointerException или IndexOutOfBoundsException, и программа продолжает работать, даже если весьма вероятно, что вы этого не хотите, потому что они часто являются фатальными.и может выйти из потока управления в неожиданных положениях.

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

0 голосов
/ 02 мая 2011

Прежде всего, трассировка стека печати не решает проблему, и проблема, вероятно, не сообщит родительскому потоку для дальнейшей обработки. Я предлагаю вам обработать исключение в предложении catch, указав тип исключения в программе с помощью e.getClass (). GetName ().

...