Стабильные коды ошибок как часть интерфейса
Формулировку сообщения мы будем менять. Код — нет. Поэтому автоматизация опирается на код, а не на подстроку в тексте.
У каждой ошибки инструмента есть собственный код. Не категория, не уровень серьёзности — конкретный код конкретной ситуации. Отсутствие конфигурации проекта, неизвестный ключ в ней, неподдерживаемая версия схемы, файл состояния в индексе git — у каждого свой.
Все коды собраны в один документ. Это часть публичного интерфейса, наравне с именами команд.
Что это меняет для автоматизации
Скрипт непрерывной интеграции может различать ситуации. «Конфигурации нет» — вероятно, неверный рабочий каталог, надо упасть. «Файл состояния попал в индекс» — надо упасть и сказать разработчику, что именно вычистить. «Неизвестный ключ» — опечатка в описании, надо показать её в отчёте сборки.
Без кодов всё это различается разбором текста сообщения. Такой разбор работает до первого улучшения формулировки, а ломается молча.
Почему код важнее текста
Текст сообщения — для человека, и он будет меняться. Мы будем его уточнять, переводить, добавлять подсказку о том, что делать. Это нормальная работа над инструментом.
Код — обязательство. Раз опубликовав его, мы не имеем права переиспользовать его для другой ситуации или изменить смысл. Это дороже, чем кажется: иногда приходится вводить новый код вместо расширения старого, потому что расширение изменило бы смысл.
Отдельно есть коды возврата процесса — для случаев, когда важно различить класс отказа, не разбирая вывод вообще. Проверка на попадание файла состояния в git завершает процесс со своим кодом возврата, а не с общей единицей.
Как это связано с честностью вывода
Стабильные коды — техническая половина правила «никакого притворного успеха». Второй половине нужна первая.
Мало отказаться возвращать пустой результат вместо ошибки. Нужно, чтобы у отказа была форма, на которую можно опереться. Иначе автор скрипта, столкнувшись с непонятной ошибкой, поставит проверку на подстроку — и мы вернёмся к исходной проблеме, только теперь по вине потребителя.
Реестр команд из той же дисциплины
Рядом с реестром кодов существует реестр команд: все команды зарегистрированы, все схемы вывода генерируются, а не пишутся руками.
Это одна и та же идея, применённая к разным сторонам интерфейса. Интерфейс, части которого описаны в одном месте и генерируются из описания, не расползается. Интерфейс, где каждая команда добавляет свои поля по вкусу автора, расползается всегда — не потому, что авторы небрежны, а потому что согласованность вручную не масштабируется.
Цена
Добавить ошибку становится дороже: надо выбрать код, внести его в реестр, описать. Это трение мешает добавлять ошибки по мелочи и заставляет думать, действительно ли это новая ситуация.
Побочный эффект оказался полезным. Вопрос «это новый код или существующий» — хороший способ обнаружить, что две разные на вид проблемы на самом деле одна.