Теория ошибок программирования

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

Теория ошибок:
Ошибки так же неисчерпаемы, как и атом.

Аксиома теории ошибок:
В любой программе есть ошибки.

Закон пропорциональности:
Чем более программа необходима, тем больше в ней ошибок.
Следствие:
Ошибок не содержит лишь совершенно ненужная программа.

Фундаментальный закон теории ошибок:
На ошибках учатся.

Следствия:
● Программист, написавший программу, становится ученым.
● Чем больше программист делает ошибок, тем быстрее он делается ученым.
● Крупный ученый-программист никогда не пишет правильные программы.
Замечание:
На то он и ученый.

Закон необходимости ошибок:
Программист может обнаружить ошибку только в чужой программе.
Следствие:
Ошибке не всё равно, кто её обнаружит.

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

Свойства программных ошибок:
● Ошибки могут следовать друг за другом.
● От перестановки двух эквивалентных ошибок результат не меняется.
● Две последовательные ошибки можно объединить в одну, более сильную.
● Одинаковые ошибки необязательно делать каждый раз, достаточно сделать одну, а затем обращаться к ней по мере необходимости из любого места программы.
● Ошибки могут образовывать циклы. Наиболее устойчивый из них — бесконечный.
● Ошибки могут вызывать друг друга и сами себя (рекурсивность ошибок).
● Ошибки допускают многократное вложение друг в друга. Две одинаковые вложенные ошибки называются четной ошибкой и ошибкой не являются.

Свойство чётности ошибок:
Если написанная программа сработала правильно, то это значит, что во время её работы выполнилось четное число ошибок или программист не понял задание.
Cвойства чётности ошибок для политиков:
Ошибка, повторенная дважды, перестаёт быть ошибкой.

Взаимодействие ошибок с базовой операционной системой:
● Во время исполнения ошибки имеют наивысший приоритет.
● Прервать исполнение ошибки может только другая, более активная ошибка.
● Запросы операционной системы к ошибкам ошибками могут игнорироваться.
● Запросы ошибок к операционной системе игнорироваться не могут.
● При работе с файлами ошибки могут пользоваться файловой системой базовой ОС и её ошибками.
● На вычислительной машине с параллельной архитектурой может выполняться несколько ошибок одновременно.
● Системные программы облегчают процесс написания прикладных программ и их ошибок.

Первое правило успешного старта проекта:
До начала работы над проектом следует тщательно продумать все необходимые ошибки и связи между ними. Это значительно упростит работу над ошибками в самом проекте.

Определение тестирования:
Тестирование — это процесс нахождения ошибок в тесте.

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

Главное свойство языкового редактора:
Языковый редактор, призванный уберечь программиста от синтаксических ошибок, позволяет вносить в программу весьма хитроумные ошибки, которые не удаётся обнаружить ни транслятором, ни отладчиком. Обычный текстовый редактор таких возможностей не предоставляет.

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

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

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

Принцип матёрого программиста:
Ошибка? Это не ошибка, это системная функция.

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

Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство.

Выдавать глобальные идеи — это удовольствие; искать отвратительные маленькие ошибки — вот настоящая работа.

Как только проект окончательно принят, он становится устаревшим в смысле своих концепций.

Настойчивость руководителя может определить график выполнения задания, но не в состоянии определить срок его действительного завершения.

Глупец, лишенный способности посмеяться над собой вместе с другими, не сможет долго выносить программирование.

Если за две минуты омлет ещё не готов, у заказчика два выбора — подождать или съесть его сырым.

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

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

Пользователь не знает, чего он хочет, пока не увидит то, что он получил.

На пустом диске можно искать вечно.

Если отладка — процесс удаления ошибок, то программирование должно быть процессом их внесения.

Вы уже дошли до состояния, когда у вас нет времени, чтобы разрешить те проблемы, которые отнимают у вас все время?

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

Вам могут понравиться

Вас может заинтересовать

Если в вашей коллекции есть другие постулаты Теории ошибок или законов Мерфи для программистов и вы хотите ими поделиться — высылайте их на наш электронный адрес. В теме письма, пожалуйста, укажите «Теория ошибок». После проверки присланный вами материал будет размещён на этой странице. Как следствие из сказанного выше: информация для размещения на страницах сайта предоставляется пользователями, комментарии читателей к представленным материалам представляют собой их частное мнение, которое может не совпадать с точкой зрения редакции «ParfumClub.org». Здесь же вы можете увидеть ссылки на онлайн-магазины с предложениями купить ту или иную продукцию. Следует отметить, что сообщество «ParfumClub.org» является некоммерческим проектом, не контролирует эти торговые площадки, не имеет к ним никакого отношения и, соответственно, снимает с себя ответственность за какие-либо последствия, которые могут возникнуть в связи с использованием таких Интернет-ресурсов.

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

Эпиграф:

«Ошибки так же неисчерпаемы, как и атом»

Приписывается Карлу Марксу и его подельникам

Аксиома. В любой программе есть ошибки.

Следствие 1. В программе, состоящей из одного оператора, есть ошибки.

Следствие 2. В программе, состоящей из N операторов, есть по крайней мере N ошибок.

Следствие 3. В программе, состоящей из одного оператора, есть по крайней мере N ошибок.

Следствие 4. В любой программе содержится бесконечное число ошибок.

Следствие 5. Чтобы познать бесконечность, нужно быть не философом, а программистом.Закон взаимосвязи программ и ошибок.

Для того, чтобы получить ошибки, надо написать программу.

Для того, чтобы получить программу, надо стараться избегать ошибок.

Следствие. Что бы вы ни делали — у вас будут получаться только ошибки.

Теорема обратимости программ и ошибок.

Всегда можно придумать программу, в которой будет не менее N ошибок.

И наоборот, всегда можно придумать ошибку, которая есть не менее, чем в N программах.

Закон пропорциональности.

Чем более программа необходима, тем больше в ней ошибок и наоборот.

Следствие 1. Совершенно ненужная программа ошибок не содержит.

Следствие 2. Ненужную программу невозможно создать ни за какие деньги.

Правило неоднозначности программ.

Даже две совершенно одинаковые программы содержат разные ошибки.

Народная примета. Сколько программистов — столько и программ.

Наблюдения системного администратора. Сколько программ — столько и неправильных результатов.

Фундаментальный закон Теории ошибок. На ошибках учатся.

Следствие 1. Программист, написавший программу, становится ученым.

Следствие 2. Чем больше программист делает ошибок, тем быстрее он становится ученым.

Следствие 3. По-настоящему ученый программист никогда не пишет правильных программ.

Замечание. На то он и ученый.

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

Наблюдение системного программиста.

Если начинающий программист написал программу, которая сразу заработала, значит она состоит только из комментариев.

Закон находимости ошибок.

Программист может обнаружить ошибку только в чужой программе или не обнаружить нигде.

Следствие 1. Администратор не может обнаружить ошибку.

Следствие 2. Ошибке не все равно кто ее обнаружит.

Следствие 3. Индивидуальная программистская деятельность невозможна.

Закон неприкосновенности ошибок.

Ошибку можно наблюдать, но нельзя исправить.

Теорема.

Исправление очевидной ошибки превращает ее в неочевидную (недоступную для наблюдения), причем этот процесс необратим.

Следствие 1. Любое активное действие, призванное улучшить программу, ухудшает программу.

Следствие 2. Пассивное наблюдение улучшает программу.

Следствие 3. Чем больше в программе очевидных ошибок, тем точнее можно предсказать результат ее работы.

Замечание. Программа без очевидных ошибок — неработоспособна.

Следствие 4. Программу проще написать заново, чем исправить.

Закон общественной полезности программиста.

Каждый человек на Земле должен быть программистом.

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

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

2) Объектное программирование — надежное средство для написания необнаруживаемых ошибок.

Закон невозможности совершения ошибки.

Получить нужную ошибку искусственным путем невозможно.

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

Следствие. Программирование с необходимыми ошибками — искусство.

Теорема о невозможности доказательства правильности программ.

Нельзя доказать, что программа не имеет ошибок.

Док-во: Не нужно доказывать, что в программе есть ошибки.

Определение.

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

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

ЯЗЫК ОШИБОК

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

Следствие. Чем ниже уровень базового языка программирования, тем ошибки более машинно-ориентированы.

Синтаксис языка ошибок определяется синтаксисом базовой системы программирования.

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

Две последовательные ошибки можно объединить в одну, более сильную.

Не любую сильную ошибку можно разбить на две более слабых.

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

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

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

Ошибки могут образовывать циклы. Наиболее устойчивый из них бесконечный.

Ошибки могут вызывать друг друга и сами себя (рекурсивность ошибок).

Ошибки могут размножаться.

Невероятно, но некоторые ошибки могут исчезать. К счастью — ненадолго.

Ошибки допускают многократное вложение друг в друга.

Две одинаковые вложенные ошибки называются четной ошибкой и ошибкой не являются.

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

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

Наблюдение программиста, полезное для юмориста.

Ошибка, повторенная дважды, перестает быть ошибкой.

Некоторые ошибки сами могут содержать ошибки (не путать с четными
ошибками). В такие минуты у неопытного программиста может сложиться
впечатление, что его программа работает правильно. Опытные программисты
активно используют такие моменты во время приемо-сдаточных испытаний.

Определение глобальности ошибок.

Ошибка называется глобальной, если поглощает все локальные по отношению к ней ошибки.

Закон экономии ошибок.

Чем более глобальную ошибку вы допустите, тем меньше будет общее число действующих ошибок.

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

ВЗАИМОДЕЙСТВИЕ ОШИБОК С ОПЕРАЦИОННОЙ СИСТЕМОЙ

Во время исполнения ошибки имеют наивысший приоритет.

Прервать исполнение ошибки может только другая, более активная ошибка.

Запросы операционной системы к ошибкам ошибками могут игнорироваться.

Запросы ошибок к операционной системе игнорироваться не могут.

При работе с файлами ошибки могут пользоваться файловой системой ОС и ее ошибками.

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

Машина искуственного интеллекта способна сама удовлетворять свою потребность в ошибках.

СИСТЕМНЫЕ ПРОГРАММЫ

Системные программы облегчают процесс написания прикладных программ и их ошибок.

Определение. Тестирование — это процесс нахождения ошибок в тесте.

Хороший тест должен содержать ошибки, компенсирующие их нехватку в тестируемой программе.

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

Закон полноты языка.
Если в языке программирования есть только одно тонкое место, делающее
язык уязвимым для ошибок, то именно оно будет использоваться
программистами наиболее часто.

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

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

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

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

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

Следствие. Хорошо продуманные ошибки залог надежной работы проектируемой программы.

Совет руководителю среднего звена.
В любой программе должны быть устранимые ошибки (т.е. хорошо отлаженные
неправильные участки программы, изъятие которых не влечет за собой
появления большого числа неустранимых ошибок), которые будут в
определенной последовательности устраняться во время приемо-сдаточных
испытаний для создания видимости отладки. Такие ошибки следует
программировать наиболее тщательно.

Закон неизменности хороших привычек.

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

Укор программистам-мужчинам.

В программах, написанных программистами-женщинами, логических ошибок значительно меньше.

Закон массовых чисел.

Среди большого числа различных чисел всегда можно выбрать необходимое.

Следствие из закона массовых чисел.
Чтобы получить правильный результат необходимо распечатать как можно
больше различных результатов и среди них выбрать необходимый.

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

ВЫВОД ИЗ ТЕОРИИ ОШИБОК

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

Автор считает, что Теория ошибок послужит надежным фундаментом для бурно развивающейся кибернетики

Disclaimer: I do not know any theory on error-handling, I did, however, thought repetitively about the subject as I explored various languages and programming paradigms, as well as toyed around with programming language designs (and discussed them). What follows, thus, is a summary of my experience so far; with objective arguments.

Note: this should cover all the questions, but I did not even try to address them in order, preferring instead a structured presentation. At the end of each section, I present a succinct answer to those questions it answered, for clarity.


Introduction

As a premise, I would like to note that whatever is subject to discussion some parameters must be kept in mind when designing a library (or reusable code).

The author cannot hope to fathom how this library will be used, and should thus avoid strategies that make integration more difficult than it should. The most glaring defect would be relying on globally shared state; thread-local shared state can also be a nightmare for interactions with coroutines/green-threads. The use of such coroutines and threads also highlight that synchronization best be left to the user, in single-threaded code it will mean none (best performance), whilst in coroutines and green-threads the user is best suited to implement (or use existing implementations of) dedicated synchronization mechanisms.

That being said, when library are for internal use only, global or thread-local variables might be convenient; if used, they should be clearly documented as a technical limitation.


Logging

There are many ways to log messages:

  • with extra information such as timestamp, process-ID, thread-ID, server name/IP, …
  • via synchronous calls or with an asynchronous mechanism (and an overflow handling mechanism)
  • in files, databases, distributed databases, dedicated log-servers, …

As the author of a library, the logs should be integrated within the client infrastructure (or turned off). This is best provided by allowing the client to provide hooks so as to deal with the logs themselves, my recommendation is:

  • to provide 2 hooks: one to decide whether to log or not, and one to actually log (the message being formatted and the latter hook called only when the client decided to log)
  • to provide, on top of the message: a severity (aka level), the filename, line and function name if open-source or otherwise the logical module (if several)
  • to, by default, write to stdout and stderr (depending on severity), until the client explicitly says not to log

I would note that, following the guidelines delineated in the introduction, synchronization is left to the client.

Regarding whether to log errors: do not log (as errors) what you otherwise already report via your API; you can however still log at a lower severity the details. The client can decide whether to report or not when handling the error, and for example choose not to report it if this was just a speculative call.

Note: some information should not make it into the logs and some other pieces are best obfuscated. For example, passwords should not be logged, and Credit-Card or Passport/Social Security Numbers are best obfuscated (partly at least). In a library designed for such sensitive information, this can be done during logging; otherwise the application should take care of this.

Is logging something that should only be done in application code? Or is it ok to do some logging from library code.

Application code should decide the policy. Whether a library logs or not depends on whether it needs to.


Going on after an error ?

Before we actually talk about reporting errors, the first question we should ask is whether the error should be reported (for handling) or if things are so wrong that aborting the current process is clearly the best policy.

This is certainly a tricky topic. In general, I would advise to design such that going on is an option, with a purge/reset if necessary. If this cannot be achieved in certain cases, then those cases should provoke an abortion of the process.

Note: on some systems, it is possible to get a memory-dump of the process. If an application handles sensitive data (password, credit-cards, passports, …), it is best deactivated in production (but can be used during development).

Note: it can be interesting to have a debug switch that transforms a portion of the error-reporting calls into abortions with a memory-dump to assist debugging during development.


Reporting an error

The occurrence of an error signifies that the contract of a function/interface could not be fulfilled. This has several consequences:

  • the client should be warned, which is why the error should be reported
  • no partially correct data should escape in the wild

The latter point will be treated later on; for now let us focus on reporting the error. The client should not, ever, be able to accidentally ignore this report. Which is why using error-codes is such an abomination (in languages when return values can be ignored):

ErrorStatus_t doit(Input const* input, Output* output);

I know of two schemes that require explicit action on the client part:

  • exceptions
  • result types (optional<T>, either<T, U>, …)

The former is well-known, the latter is very much used in functional languages and was introduced in C++11 under the guise of std::future<T> though other implementations exist.

I advise to prefer the latter, when possible, as it easier to fathom, but revert to exceptions when no result is expected. Contrast:

Option<Value&> find(Key const&);

void updateName(Client::Id id, Client::Name name);

In the case of «write-only» operations such as updateName, the client has no use for a result. It could be introduced, but it would be easy to forget the check.

Reverting to exceptions also occur when a result type is impractical, or insufficient to convey the details:

Option<Value&> compute(RepositoryInterface&, Details...);

In such a case of externally defined callback, there is an almost infinite list of potential failures. The implementation could use the network, a database, the filesystem, … in this case, and in order to report errors accurately:

  • the externally defined callback should be expected to report errors via exceptions when the interface is insufficient (or impractical) to convey the full details of the error.
  • the functions based on this abstract callback should be transparent to those exceptions (let them pass, unmodified)

The goal is to let this exception bubble up to the layer where the implementation of the interface was decided (at least), for it’s only at this level that there is a chance to correctly interpret the exception thrown.

Note: the externally defined callback is not forced to use exceptions, we should just expect it might be using some.


Using an error

In order to use an error report, the client need enough information to take a decision. Structured information, such as error codes or exception types, should be preferred (for automatic actions) and additional information (message, stack, …) can be provided in a non-structured way (for humans to investigate).

It would be best if a function clearly documented all possible failure modes: when they occur and how they are reported. However, especially in case arbitrary code is executed, the client should be prepared to deal with unknown codes/exceptions.

A notable exception is, of course, result types: boost::variant<Output, Error0, Error1, ...> provides a compiler-checked exhaustive list of known failure modes… though a function returning this type could still throw, of course.

How to decide between logging an error, or showing it as an error message to the user?

The user should always be warned when its order could not be fulfilled, however a user-friendly (understandable) message should be displayed. If possible, advices or work-arounds should be presented as well. Details are for investigating teams.


Recovering from an error ?

Last, but certainly not least, comes the truly frightening part about errors: recovery.

This is something that databases (real ones) are so good for: transaction-like semantics. If anything unexpected occurs, the transaction is aborted as if nothing had happened.

In the real world, things are not simple. The simple example of cancelling an e-mail sent pops to mind: too late. Protocols may exist, depending on your application domain, but this is out of this discussion. The first step, though, is the ability to recover a sane in-memory state; and that is far from being simple in most languages (and STM can only do so much today).

First of all, an illustration of the challenge:

void update(Client& client, Client::Name name, Client::Address address) {
    client.update(std::move(name));
    client.update(std::move(address)); // Throws
}

Now, after updating the address failed, I am left with a half-updated client. What can I do ?

  • attempting to undo all the updates that occurred is close to impossible (the undo might fail)
  • copying the state prior to executing any single update is a performance hog (supposing we can even swap it back in a sure way)

In any case, the book-keeping required is such that mistakes will creep in.

And worst of all: there is no safe assumption that can be made as to the extent of the corruption (except that client is now botched). Or at least, no assumption that will endure time (and code changes).

As often, the only way to win is not to play.


A possible solution: Transactions

Wherever possible, the key idea is to define macro functions, that will either fail or produce the expected result. Those are our transactions. And their form is invariant:

Either<Output, Error> doit(Input const&);

// or

Output doit(Input const&); // throw in case of error

A transaction does not modify any external state, thus if it fails to produce a result:

  • the external world has not changed (nothing to rollback)
  • there is no partial result to observe

Any function that is not a transaction should be considered as having corrupted anything it touched, and thus the only sane way of dealing with an error from non-transactional functions is to let it bubble up until a transaction layer is reached. Any attempt to deal with the error prior is, in the end, doomed to fail.

How to decide if an error should be handled locally or propagated to higher level code ?

In case of exceptions, where should you generally catch them? In low-level or higher level code?

Deal with them whenever it is safe to do so and there is value in doing so. Most notably, it’s okay to catch an error, check if it can be dealt with locally, and then either deal with it or pass it up.


Should you strive for a unified error handling strategy through all layers of code, or try to develop a system that can adapt itself to a variety of error handling strategies (in order to be able to deal with errors from 3rd party libraries).

I did not address this question previously, however I believe it is clear than the approach I highlighted is already dual since it consists of both result-types and exceptions. As such, dealing with 3rd party libraries should be a cinch, though I do advise wrapping them anyway for other reasons (3rd party code is better insulated beyond a business-oriented interface tasked with the impedance adaption).

Теория программирование | Ошибки

276

1

16

11.05.2023

Евгений Черкашин

Евгений Черкашин

22164

368

136

10.10.2011

СКАЧАТЬ ВИДЕО

Описание видео:

Программирование.
Рассматриваются различные аспекты феномена ошибок.
1. Ошибки в языках уровня С (значения функций вне диапазона)
2. Исключения и их перехват
3. Конструкции типа Maybe в языках с расширенной обработкой типов.
4. Варианты обеспечения надежности длительных вычислительных процессов.

Кадры из видео

Теория программирование | Ошибки

Теория программирование | Ошибки

Теория программирование | Ошибки

Теория программирование | Ошибки

Тэги из видео

Комментарии пользователей:

Порой обучение продвигается с трудом. Сложная теория, непонятные задания… Хочется бросить. Не сдавайтесь, все сложности можно преодолеть. Рассказываем, как

Не понятна формулировка, нашли опечатку?

Выделите текст, нажмите ctrl + enter и опишите проблему, затем отправьте нам. В течение нескольких дней мы улучшим формулировку или исправим опечатку

Что-то не получается в уроке?

Загляните в раздел «Обсуждение»:

  1. Изучите вопросы, которые задавали по уроку другие студенты — возможно, ответ на ваш уже есть
  2. Если вопросы остались, задайте свой. Расскажите, что непонятно или сложно, дайте ссылку на ваше решение. Обратите внимание — команда поддержки не отвечает на вопросы по коду, но поможет разобраться с заданием или выводом тестов
  3. Мы отвечаем на сообщения в течение 2-3 дней. К «Обсуждениям» могут подключаться и другие студенты. Возможно, получится решить вопрос быстрее!

Подробнее о том, как задавать вопросы по уроку

Понравилась статья? Поделить с друзьями:
  • Теплостар 4дм 24 коды ошибок
  • Теория ошибок наблюдений большаков
  • Теоретическая вероятность ошибки
  • Теплостар 14тс 10 коды ошибок 24в
  • Теория ошибок метаэтика