Получение корневых сообщений об ошибках от Throwable - PullRequest
1 голос
/ 04 апреля 2011

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

catch (Throwable t) {
    ...
    t.getMessage();
    ...
}

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

не удалось вставить [some.class.name.Here]

, чтоочень бесполезно.Фактическая причина ошибки была скрыта в трассировке стека:

Допустимы только даты между 1 января 1753 года и 31 декабря 9999 года.

Учитывая первую ошибкусообщение, я бы понятия не имел, что пошло не так.Учитывая второе, я бы, по крайней мере, знал бы, чтобы посмотреть на дату, которую я ввел.Чтобы решить эту проблему, я сделал это:

catch (Throwable t) {
    ...
    ExceptionUtils.getExceptionMessageWithCauses(t);
    ...
}

...

public class ExceptionUtils
{
    public static String getExceptionMessageWithCauses(Throwable t)
    {
        if ( t.getCause() == null ) {
            return t.getMessage();
        } else {
            return t.getMessage() 
                + "; caused by: " 
                + getExceptionMessageWithCauses(t.getCause());
        }
    }
}

Моя первая задача - попасть в какой-то бесконечный цикл, если два класса Throwable ссылаются друг на друга.Или, аналогично, первопричина настолько глубока, что даже отображение более удобного сообщения об ошибке из Throwables приводит к чему-то не лучше, чем трассировка стека.Итак, два вопроса:

  1. "Безопасно ли" делать что-то подобное или люди могут подумать о случаях, когда это взорвется мне в лицо?

  2. Есть ли лучший способ обработки исключений, кроме проверки каждой возможной ошибки по очереди?

Спасибо!

1 Ответ

2 голосов
/ 04 апреля 2011

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

Что мы делаем, это перехватываем все исключения, которые могут что-либо значить для пользователя (обычно это проверенные исключения), все остальные исключения (обычно RuntimeExceptions) просто обрабатываются сообщением «Произошла внутренняя ошибка».

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

Edit:

Иногда может потребоваться перебрать причины, чтобы получить отображаемое исключение. Например, у нас есть исключения, которые вызываются нашим уровнем персистентности, но они передаются через уровень EJB и, таким образом, заключаются в EJBExceptions. Таким образом, мы перебираем причины до тех пор, пока не найдем одно из наших исключений и не выведем красивое сообщение или не отобразим сообщение «внутренняя ошибка».

Обратите внимание, что обычно пользователь никогда не должен сталкиваться с сообщениями об ошибках по умолчанию, так как большинство из них не знает, что это значит ("Ха, что такое NullPointerException ????")

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