Должны ли вы сообщить текст сообщения об исключениях?
Рассмотрим некоторый код, который может генерировать проверенное исключение (исключение типа Exception
). Ваш код catch
Конечно, исключение. Вы не просто проглатываете исключение, ваш код каким-то образом сообщает об этом пользователю через ваш пользовательский интерфейс. Возможно, в файле журнала или с помощью всплывающего окна с графическим интерфейсом.
Если текст, который вы сообщаете пользователю, включает текст сообщения об исключении. То есть текст предоставлен Throwable.getMessage()
или же Throwable.getLocalizedMessage()
?
Я думаю, что нет, но, похоже, многие со мной не согласны. Так в чем я ошибся? Мой аргумент заключается в следующем.
- Сообщение было создано при возникновении исключения. Следовательно, в лучшем случае он может предоставлять информацию только очень низкого уровня, которая может быть неприемлемой для сообщения пользователю.
- С философской точки зрения использование сообщения кажется мне против всей точки исключения, которая заключается в том, чтобы отделить обнаружение и инициирование обработки ошибок (
throw
часть) от завершения обработки и отчетности (catch
часть). Использование сообщения означает, что сообщение должно быть пригодным для создания отчетов, что переводит ответственность за отчетность в местоположение, которое должно отвечать только за обнаружение и инициирование. То есть я бы сказал, чтоgetMessage()
часть дизайнаThrowable
было ошибкой. - Сообщение не локализовано. Несмотря на свое название,
getLocalizedMessage()
не очень хорошо, потому что вы можете не знать, какой язык вы хотите использовать, пока выcatch
исключение (это отчет для перехода в системный журнал, прочитанный вашими английскими системными администраторами, или это всплывающее окно в окне для французского пользователя GUI?). - Я слышал, что в Java 7 значительно улучшена иерархия исключений для
IOException
, что позволяет обрабатывать различные виды ошибок ввода / вывода в разныхcatch
пункты, делающиеgetMessage()
текст менее важен. Это подразумевает, что даже Java-дизайнеры несколько неудобны сgetMessage()
,
Я не спрашиваю, полезна ли отчетность по трассировке стека. Трассировка стека будет полезна только для исключения, которое предполагает ошибку. То есть для неконтролируемого исключения. Я думаю, что в таких обстоятельствах предоставление низкоуровневой детализации сообщения об исключении не только полезно, но и обязательно. Но мой вопрос касается проверенных исключений, таких как file-not-found.
4 ответа
Если вы представляете пользователю ошибку, вероятно, это должно быть удобное сообщение. Исключения содержат технические детали, которые пользователь не должен / не должен знать.
В некоторых ситуациях представление информации о трассировке стека может быть проблемой безопасности, поэтому пользователю никогда не следует показывать трассировки стека.
Если вы отображаете сообщения об ошибках для пользователя, есть момент, когда вы сознательно принимаете решение показать всплывающее окно или добавить сообщение в окно журнала. На этом этапе вы можете перевести любое исключение в более удобное для пользователя сообщение. Обратите внимание, что вам может потребоваться больше информации, чем по умолчанию Exception
типы предоставляют, так что вы можете / должны создать свой собственный Exception
типы, которые содержат всю информацию, необходимую для представления всех данных, необходимых пользователю.
Нет, исключения не должны отображаться непосредственно в сообщениях об ошибках непосредственно пользователю, они являются техническими подробностями низкого уровня, и пользователь почти всегда хочет что-то более понятное, даже если он не предоставляет столько информации, сколько было бы в трассировке стека!
Я говорю почти всегда, потому что есть случаи (например, в IDE), где вы можете считать своих пользователей достаточно технически компетентными для просмотра трассировки стека; действительно, в этом случае они, вероятно, предпочтут это "тупое" сообщение об ошибке.
Тем не менее, лично я думаю, что следы стека всегда должны регистрироваться где-то, к чему пользователь может получить доступ, чтобы, если они жалуются, что "программа не работает", вы можете точно увидеть, что произошло, если они отправят вам этот файл.
В некоторых проектах я делаю особые исключения (например, UserFriendlyException). Этот тип исключения должен иметь удобное сообщение об ошибке. Если я поймаю такое исключение, я могу показать его пользователю.
Это позволяет использовать исключения для удобных для пользователя ошибок и предотвращает показ очень технических сообщений пользователю.
Я бы сказал, что вы никогда не должны показывать пользователю само сообщение об исключении, оно должно появляться только в журнале. Даже если вы намеренно сделали его удобным для пользователя, он все равно не должен отображаться, поскольку вы не можете легко интернационализировать эти сообщения. Вам следует придумать какой-то механизм, который может понять ваш уровень пользовательского интерфейса, и разрешить его в коде, который вы можете найти в интернационализированном сообщении, которое будет отображаться вашему пользователю. Я обнаружил, что исключение с атрибутом / перечислением "код" работает довольно хорошо. Также работают очень специфические исключения, но это может быть грязно, чтобы поддерживать.