правильно распечатать трассировку исключений сервлета - PullRequest
4 голосов
/ 19 мая 2009

, поэтому я использую фильтр, чтобы перехватить исключение сервлета (потому что мы используем смесь сервлетов jsf / plain)

при перехвате ServletException и вызове printstacktrace большая часть информации теряется.

"истинное" корневое исключение, кажется, скрыто за "забавным" выражением

((ServletException) e.getRootCause().getCause()).getRootCause().getCause().getCause().getCause()

это явно не способ сделать это.

- это простой способ распечатать «полную» информацию о таком исключении. Может кто-нибудь объяснить мне, почему исключение обернуто таким образом?

Ответы [ 4 ]

6 голосов
/ 19 мая 2009

Взгляните на класс ExceptionUtils от commons-lang. Он содержит несколько полезных методов для печати всей цепочки исключений.

3 голосов
/ 19 мая 2009

после того, как я взглянул на ExceptionUtils, это решило проблему!

    final StringWriter stacktrace = new StringWriter();
    ExceptionUtils.printRootCauseStackTrace(throwable,new PrintWriter(stacktrace));
    msg.append(stacktrace.getBuffer());

распечатывает полную трассировку стека с каждым релевантным фрагментом информации.

1 голос
/ 19 мая 2009

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

Пример:

public void doStuff() throws StuffException {
    try {
        doDatabaseStuff();
    } catch (DatabaseException de1) {
        throw new StuffException("Could not do stuff in the database.", de1);
    }
}

Таким образом, ваше приложение должно обрабатывать только StuffException, но оно может добраться до базового DatabaseException, если оно действительно необходимо.

Чтобы добраться до самого нижнего (и всех других) исключений, которые вы поймали, вы можете выполнить итерацию по его основным причинам:

    ...
} catch (SomeException se1) {
    Throwable t = se1;
    logger.log(Level.WARNING, "Top exception", se1);
    while (t.getCause() != null) {
        t = t.getCause();
        logger.log(Level.WARNING, "Nested exception", t);
    }
    // now t contains the root cause
}
0 голосов
/ 24 августа 2015

Цепочка исключений для ServletException сложна. В зависимости от реализации веб-сервера и используемой среды веб-разработки, во время выполнения цепочка может использовать причину и / или rootCause. Эта ссылка объясняет это очень хорошо. Чтобы усложнить ситуацию, я видел исключения, в которых причина указывает на само исключение. Вот рекурсивный метод, который мы использовали, который охватывает все базы для исключений ServletException:

public static Throwable getDeepCause(Throwable ex) {
    if (ex == null) {
        return ex;
    }
    Throwable cause;
    if (ex instanceof ServletException) {
        cause = ((ServletException) ex).getRootCause();
        if (cause == null) {
            cause = ex.getCause();
        }
    } else {
        cause = ex.getCause();
    }
    if (cause != null && cause != ex) {
        return getDeepCause(cause);
    } else {
        // stop condition - reached the end of the exception chain
        return ex;
    }
}
...