Как вы назначаете коды ошибок?

13

Как при разработке проекта среднего размера вы можете идентифицировать, создавать и поддерживать коды ошибок?

Я за свою жизнь не могу придумать простой и чистый способ сделать это. Некоторые из моих идей преобразовывают имена классов и имен методов в целочисленную строку, но это слишком длинный способ отображать пользователю поверх факта, что имена методов и имена классов могут изменяться (надеюсь, нет!). Другие просто используют возрастающую систему журналов (т.е. когда я создаю новое сообщение об ошибке, просто добавьте 1 к последнему идентификатору сообщения об ошибке). Но это просто неорганизованно.

Чтобы быть более конкретным, я говорю о коде ошибки, таком как:

Error 401 Unauthorized.

ahodder
источник
1
коды ошибок? Как "магические числа"? Например ... ОШИБКА 001. Затем вы идете в список и читаете ОШИБКА 001 означает, что бла-бла-бла ... Да?
wleao
@wleao - Да, сэр. Я отредактирую свой вопрос, чтобы охватить это. Спасибо.
ahodder
Прочитайте это: en.wikipedia.org/wiki/Magic_number_%28programming%29
wleao
Как вы редактировали в своем вопросе. Посмотрите, как они делают это с http. Я не знаю, стоит ли вообще использовать магические числа. Однако, если вы действительно хотите это сделать, следуйте их концепциям. Например, у них есть таксономия ошибок (у вас есть это?).
wleao
@wleao - пока нет, но благодаря вам и Петеру Тёроку я обязательно буду его создавать. :)
ahodder

Ответы:

16

Нет.

Коды ошибок являются анахронизмом, они берут свое начало в те старые времена, когда вывод был действительно сложным и дорогим, и единственный способ сообщить об ошибке, возможно, был через несколько индикаторов на передней панели: pdp11 / 70 передняя панель

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

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

tdammers
источник
Спасибо за подробный ответ, который имеет большой смысл и полезно знать.
ahodder
Ваше использование иллюстраций полностью соответствует вашему аргументу. Я читал о PDP-11 навсегда. Но это на самом деле первый, который я когда-либо видел. Благодарю.
Майк Оуэнс
2
Внутри кода я бы предпочел обработать код ошибки, и я не такой уж старый.
JeffO
@Jeff: Все, что вы можете сделать с кодами ошибок, также может быть сделано с исключениями, а затем немного больше. Если вы хотите имитировать коды ошибок с исключениями, все, что вам нужно сделать, это бросить вместо того, чтобы возвращать код ошибки, и поймать вместо сравнения возвращаемого значения с E_OK (или любым другим ответом OK). Чтобы быть справедливым, C не имеет реальных исключений, и longjump не так удобен, поэтому, если вы делаете C, вы несколько извиняетесь.
tdammers
@Mike: Изображение из статьи в Википедии о серии PDP-11; если это не легко найти, я не знаю, что есть.
tdammers
6

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

Петер Тёрёк
источник
Добавьте к своему ответу таксономию. Это облегчит управление и исправление ошибок.
wleao
3

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

(Предполагая, что ваш язык поддерживает исключения.)

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

Дэн
источник
Это очень верно, и я делаю это, но что я скажу пользователям? Я уверен, что они были бы в ярости, если бы торговали ими, а приложение просто умирало, без объяснений или чего-либо еще.
ahodder
6
Я думаю, что здесь есть как минимум три разные вещи, которые запутываются здесь. Первый - это коды, используемые из программного обеспечения в программное обеспечение, как в HTTP. Второй - это коды, которые пользователи могут использовать в отчете об ошибках (например, номера инцидентов). Последние - это сообщения, которые могут быть показаны пользователю. Это может помочь рассмотреть их как отдельные вещи.
Дариен
2
Одна из важных причин использовать коды ошибок - это когда вы создаете серверное приложение. Клиентской программе намного проще и элегантнее интерпретировать и реагировать на код, чем на сообщение об ошибке или трассировку стека. Не все ошибки связаны с ошибками.
Кайпро II
1
Исключения очень сложны, чтобы получить право! Смотрите ссылки в: programmers.stackexchange.com/questions/97874/…
Кодер
@Coder: ваш пример использует исключения. Вы должны поймать то, что вы ожидаете бросить . Большинству методов не нужно ожидать выдачи даже одного исключения. Программист несет полную ответственность за решение, что делать, и я согласен, что может быть трудно сделать это правильно .
Дан
2

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

Вы должны использовать коды ошибок, локальные для каждого модуля. Для библиотеки у вас может быть специальный заголовок со списком кодов ошибок, с номерами 1, 2 и т. Д. (Или -1, -2, если вы предпочитаете). Обязательно всегда возвращайте один из этих кодов, например, переводите errnoв свои собственные коды. Если у вас есть несколько уровней модулей, переводите на каждом шаге (или задайте диапазон для более глубокой ошибки, например, значения 1001 - 1050 взяты из этого другого модуля).

Также важно, чтобы вы предоставили средства для перевода кода в строку. Вы никогда не должны сообщать только код, который только приводит к разочарованию. На самом деле практически любой код в вашем приложении должен иметь функцию перевода строки. Например, libc обычно имеет strerrorи strsignal, но, к сожалению, не хватает strwaitstatus.

Пер Йоханссон
источник
фантастическая деталь, спасибо. Это действительно очень полезно.
2