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

Но про какой бы уровень мы бы не говорили, все строится вокруг простого утверждения, которое я постараюсь раскрыть ниже:

>
Ошибок быть не должно.

Понимание

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

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

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

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

Программы

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

В большинстве ЯП, такая штука называется исключением. Потому что когда дизайнили эти языки программирования, ошибки рассматривали как что-то исключительное. Языки и экосистемы дизайнили только для выполнения “положительного исхода”. Но сегодня очевидно, что это не так. Может быть, функция вычисления логарифма и кажется, что должна работать всегда, потому что она работает с числами. Но даже это не так. И разработчику нужно решать, как программа должна себя повести в случае, если по бизнес логике выходит, что в функцию логарифма нужно засунуть 0.

И вот мы, на примере, можем определить два разных использований слова “ошибка”.

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

Второй - это человеческий фактор. Неправильность использования инструментов. Почему инструментом воспользовались не правильно - не важно. Может быть сам инструмент спроектирован не правильно, может быть у человека не хватило компетенции учесть сложность его использования. Важно, что им воспользовались не правильно. Это и является целью действий по исправлению ошибки.

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

Бизнес логика

Бизнесу нужно, что бы все работало идеально для себя и для своего клиента. Планка идеальности, конечно же, устанавливается на основе затрачиваемых на поддержание ресурсов.

Сначала бизнес продумывает успешный путь оказания услуги пользователю. Можно даже заметить, что компании часто первые запуски каких-то новых продуктов делают бесплатными. А потом закручивают гайки и добавляют монетизацию или какую-то другую оплату за свои услуги, например предоставляемые данные. Потому что такой паттерн ведения достаточно удобен - разработчики сначала делают клиентскую часть и запускают MVP. А потом, пока собирается аналитика, кодится биллинг.

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


Очень абстрактно написал, но вот пример.

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

Потом бизнес узнает, что СМС могут не доставляться по разным причинам: устройство их не принимает, абонент специально отключил у оператора функцию СМС на свой номер, и ещё сотня специфичных причин, вплоть до технических проблем на стороне провайдеров. И тут бизнес начинает интегрировать с другими провайдерами, ищет новые более эффективные способы доставки информации.

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

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

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


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

Такой процесс развития кодовой базы нам нравится, потому что уменьшает количество ошибок.

API

База данных