Pull to refresh

Comments 16

Для java монаду Either уже реализует www.vavr.io Ну, и статья заканчивается примерно там, где начинается ее заголовок — как представлять ошибки в коде, описано, а как их обрабатывать уже нет.
Если проект ориентирован на GUI, то ошибки подразделяются в прикладном смысле еще на 2 вида: Пользовательские и Системные.
Пользовательские — те, которые должны отображаться клиенту с нормальным текстом.
Все системные ошибки пользователь видит всегда как одну, например, Внутренняя ошибка сервера.
У большинства разработчиков, начинаются трудности в понимании, какую ошибку нужно выбрасывать в том или ином случае.

Вот здесь бы пару рецептов и лучших практик услышать…

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

UFO just landed and posted this here
Я бы добавил ещё, что есть одни и те же ошибки(как системные так и пользовательские), которые в одних случаях нужно отображать, а в других должны пройти тихо с записью в лог.
Опыт показывает, что к «внутренней ошибке сервера» все равно лучше добавить какое-то разъяснение. Либо хотя бы пару осмысленных строчек (только не очень длинных и страшных для непосвященных), либо некий id ошибки или сессии, по которому затем на сервере ее можно будет найти в логах.
Иначе как обычно: пользователь жалуется что у него ничего не работает, сообщение об ошибке неинформативное (та самая «внутренняя ошибка» и все), а на сервере в логи постоянно валится столько всего, что отследить какая именно ошибка случилась у этого пользователя без дополнительных подсказок очень сложно.
Ваша правда. С нашей стороны, более жизненный кейс — когда заказчик присылает скриншот от клиента, Внутренняя ошибка сервера и все. Требуется разобраться срочно, а логов нет, или не дают или присылают через 3 дня. Тогда, наличие дополнительного кода — это просто подарок.
С другой стороны, тот же заказчик выставляет определнные требования к ошибкам, отдел безопасности выставляет требования к сокрытию данных, да и самих клиентов порой выбешивает — Внутренняя ошибка сервера. EA125. Вот и получается, что не все так однозначно… :)

Исключения — это не ошибки, а прерывание нормального потока исполнения. Значит, если вы для себя рассчитываете "вот, у меня тут могут возникнуть какие-то ошибки, но поток исполнения это не будет прерывать, я их как-то обработаю" — то используйте не исключения, а какие-то специальные значения.

Добавлю свои пять копеек.
Любая серьёзная ошибка, если она не замыкается на сервере или в глубине приложений, должна иметь возможность доехать до техподдержки, чтобы она могла самостоятельно или с помощью разработчиков объяснить пользователю, что делать дальше. Т.е. в интерфейсе заранее предусматривается страница с ошибкой, на которой выводится код ошибки и какая-либо подробная информация о случившемся, которую пользователь может передать в техподдержку голосом или через e-mail по кнопке «Сообщить об ошибке».

Для формирования кода ошибки каждый модуль приложения/сервера нумеруется, а внутри него нумеруются все места, кидающие ошибки/исключения. И на выходе получаем код ошибки как
module * 100 + errorNumber

Который передаётся с нижних уровней до UI в классе, подобному
/**
 * Описание ошибки, которое передаётся для отображения и обработки с нижних уровней в UI
 */
data class ErrorDescription (
    val fatal: Boolean,     // степень важности ошибки:
                            // если true, то дальнейшая работа приложения не возможна, показываем диалог "переустановите или обратитесь к разработчику"
                            // false - показываем "попробуйте повторить операцию"
    val code: Int,          // код ошибки, см. ниже
    val desc: String,       // описание ошибки для пользователя
    val exMessage: String = "",  // сообщение в исключении
    val stackTrace: String = "" // stack trace исключения
)

Если ошибка приезжает с сервера, то достаточно иметь code и desc, чтобы техподдержка могла быстро её найти в серверных логах.

В статье смешивается понятие ошибки и исключения. Ошибка — это именно ошибка в коде, когда тот работает не так, как задумывалось. Например, фабрика возвращает null вместо объекта.
Исключение — когда код работает корректно и происходит что-то нестандартное, но вполне нормальное — например, отсутствует файл, не отвечает сервер, пользователь ввёл кривые данные.
Соответсвенно, исключения надо обрабатывать и сообщать о них, а подход к ошибкам может быть самым разным, и остановка программы — тоже неплохой вариант.

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

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

Если программа может сообщить что не так, значит в принципе об этом было известно и тому, кто добавил вывод сообщения об ошибке.
Если возникает ошибка, которую никто не предполагал (а иначе её бы не было), то программа может остаться в неожиданном состоянии и экстренное завершение — довольно адекватный вариант. Допустим, в таком случае можно поставить глобальный обработчик и делать дамп всего что только можно и, проверяя его наличие при запуске, предлагать отправить отчёт.

Разработчики мобильных приложений могут даже не догадываться, какой из дальних микросервисов может сбойнуть и вернуть ошибку. Причём ошибки могут быть плавающими из-за временной недоступности каких-либо интеграционных сервисов (кто-то патч-корд выдернул, DNS лежит и т.д. и т.п.). И что, каждый раз падать? Или просто сказать «Код ошибки 50431, попробуйте повторить операцию позже».

Особенно это касается встраиваемых систем, представьте, что у марсохода сбоит гироскоп/термометр/дальномер/камера, он куда будет дамп скидывать для отчёта?

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

Прочитайте внимательно, пожалуйста.


Если возникает ошибка, которую никто не предполагал

Отказ удаленного сервиса (особенно 3rd party) — это не ошибка приложения, а прогнозируемое поведение, которое не оставит приложение в неопределённом состоянии.


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

Демагогия. Если уж так, то «ошибок, которых никто не предполагал» вообще нет. Чисто логически это доказывается тем, что есть я, который предполагает, наличие любой возможной ошибки, в любой возможной системе. Вы же не уточнили, круг этих никого :) А если исходить из реалий, то отказ удаленного сервера — вполне себе ошибка, которую разработчик не предполагал, но и убивать приложение из-за этого не надо.
Собственно, вы же, наверное, подходя к перекрестку не вызываете заранее машину скорой помощи, потому что не предполагаете, что вас собьёт машина. Но, если не дай бог это случится, то и добивать Вы себя не станете, правда?
Sign up to leave a comment.

Articles