Но в статье я поднимаю немного другую тему: как сделать так, чтобы даже ошибки возникли система продолжала работать насколько это возможно, а пользователь не сталкивался с крашем, потерей данных или “горящим” интерфейсом и надеждой, что его починят как можно скорее. Идеального кода не бывает, а отказоустойчивость — это как раз про то, что делать, когда идеал дал трещину.
Вот именно! Практически в 100% случаев, попытка "продолжить работу после ошибки" - приводит к тому, что система становится не просто бесполезной, но - активно вредной.
Вот у вас нет памяти. Вы начинаете "обходить" ошибки выделения памяти, в результате - теряете данные, пользователь об этом не знает - и получает потерю или искажение пользовательских данных.
Например, разработчик текстового редактора (уровня OpenOffice/MS Word), если попробует "обходить" и "восстанавливаться" после проблем нехватки памяти - запросто может потерять часть документа. Или, например, вставленные рисунки. После чего пользователь этот документ сохраняет - и привет.
Практически единственный пример, когда "обход" ошибок выделения памяти оправдан - это если вы непосредственно по команде пользователя пытаетесь сделать что-то, требующее выделения большого-большого блока памяти, начинаете операцию с выделения памяти - и вот тут реально можно проверить, что память не выделена и операцию выполнить не удастся. И об этом удастся сообщить пользователю, т.к. свободная память ещё есть.
А вот если вы начали большую операцию, выделяете память мелкими кусочками по-объектно, и вот где-то в середине у вас обломалось выделение очередного мелкого объекта - вам кирдык.
Вы не сможете ни сообщить об этом пользователю, ни откатить операцию - так как памяти у вас вообще нет. А на сообщения и откат - сюрприз - нужна память.
Я такое проходил. Допустил утечку памяти, причём, малыми кусочками. За месяц непрерывной работы, память тупо кончилась вся. И дальше, так как программа именно была ориентирована на "продолжение работы" - начала терять функции интерфейса. Пункты из меню. Элементы интерфейса.
Что выглядело совершенным безумием для пользователя. Причём если бы она просто грохнулась - пользователь просто запустил бы её заново.
А, вот откуда появлется куча "программистов", постоянно использующих паттерн:
let data;
try
{
data = this.getSomeData();
} catch(error)
{ data = this.getErrorData();
console.error(error); }
this.doSomething(data);
А ещё паттерн:
bool someFunc(Param * param)
{
if (nullptr == param) return false;
....
}
И ещё хорошо, если ошибку залогируют.
Возможно, если хорошо прищуриться, это может в каких-то редких случаях иметь смысл при разработке фронтенда на JS.
Но! Вот такой подход категорически, абсолютно недопустим при разработке абсолютно любых реально используемых для чего-то разумного продуктов.
Самый разумный подход: это при обнаружении ошибки, которую вы не знаете как можно обработать - немедленно паниковать с сохранением достаточной информации (где и почему) запаниковало.
Попытки продложить работу, если вы обнаружили не предусмотренную вашим алгоритмом ошибку - их необходимо категорически исключить. Продолжая работу при ошибке - вы а) сделаете хуже б) затрудните обнаружение и исправление ошибки.
Включите в ваш набор инструментов аналог макроса assert (я предпочитаю комбинацию verify()/halt())который никогда не отключается, в том числе в релизной сборке.
Активно применяйте его для проверки входных данных, выходных данных, возвращаемых значений и промежуточных условий/утверждений.
Подход "оборонительного программирования" - не означает, что вы должны паниковать и завершать работу, если пользователь указал для сохранения данных файл, не доступный на запись, или если сетевое соединение разорвалось.
Вы можете корректно и разумно обработать эти события? Обрабатывайте. Не можете или вам лень вот прямо сейчас писать код обработки? Ставьте verify().
Но вот если вам в функцию передали nullptr, и в спецификации функции не указано, что "вот этот параметр можно поставить null и поведение будет следующим ..." - паникуйте. Никогда, ни при каких условиях не надо пытаться "маскировать" ошибку.
Читать почту и отвечать на почту. А для того, чтобы ответить на почту - надо знать, что отвечать.
И да, есть такой небольшой нюанс: у нейросети нет отдельного входа для "данных снаружи" и "данных изнутри".
Их можно маркировать "данные присланные снаружи" и "внутренние данные" - но нейросеть технически никак не ограничена в том, чтобы эти данные не могла попутать.
Точно так же, как человек может забыться и в ответ на электронной письмо с незнакомого адреса ответить какой-нибудь конфеденциальной информацией. Типа: "ой, не подумал".
---------------
Теоретически, если у нейросети просто нет доступа к "закрытой" информации - а только к открытой - она не сможет её разгласить. Но тогда особого смысла в этой нейросети и нет.
То есть я правильно понимаю - вместо литературных текстов, системе глубокого обучения дали на вход 22 миллиона спецификаций ферментов и описания их свойств, а далее - для спецификации фермента предложили описать его свойства?
Охренительно. То есть модель никакого физического представляения о самом ферменте (и том, как он работает в огранизме) не имеет, но выдаёт "похожие на настоящие" описания?
Угу. Они покупают комплектующие у американских компаний. А вот производят ли они эти комплектующие в США - или импортируют из Китая - это уже второй вопрос.
И есть большое подозрение, что на каком-то уровне резко выясняется, что "а вот это мы купили в Китае".
Первое, что делаешь, когда сервис не может что-то открыть/запустить/увидеть - отрубаешь SELinux. В большинстве случаев - помогает.
Самоё печальное, что даже в операционках, в которых SELinux поставляется включённым по умолчанию, пакеты установленные из штатного системного репозитария - могут нифига не устанавливать нужные им для функционирования права доступа. Даже такой стандарт, как апач.
А по поводу решения Торвальдса делать отдельную отключаемую приблуду - на самом деле, в этом он был абсолютно прав.
Реально, исторические права доступа в Юниксе - это тот разумный минимум, которым будет пользоваться 95%-98% пользователей. Достаточно просто и удобно, чтобы можно было пользоваться постоянно - и достаточно возможностей/функционала, чтобы решить практически все реальные задачи ограничения прав доступа.
Подход, который реализован в SELinux ( и в системе ограничения прав доступа в Windows ) - он продиктован идеей "давайте сделаем супер-пупер систему, пригодную для суперсекретной деятельности". По спецификации уродов из спецслужб США, которым абсолютно насрать на удобство использования, главное - чтобы "секьюрно".
В результате, 99% пользователей даже и не пытаются с этой системой разобраться. А значит, в принципе не пользуются. А если пользуются - то хрен его знает, не открыто ли там чего лишнего.
"Вся эта документация и проверка относительно десятков «корпоративных стандартов разработки», приемо-сдаточные испытания, проверка кибербезопасности, выкладвание в Реестр Российского ПО, проверка на 4-й уровень доверия ФСТЭК и куча другой бумагомарательной необходимой работы — в идеале будет делаться автоматически."
Вы понимаете, что это одна из проблем внедрения генерирующих нейронных сетей?
Ведь вся эта бумага, вся это "ненужна документация" и "стандарты кодирования" - они все сделаны не для того, чтобы испортить настроение разработчика. Это всё сделано для того, чтобы продуктом можно было нормально пользоваться и его развивать - человеку.
Если вы всё это отдаёте "нейросетям" - значит, можете с тем же успехом всё это просто выкинуть.
Даже хуже - отсутствие документации лучше, чем наличие бессмысленной сгенерированной документации. Которая выглядит почти как настоящая, и на 80% действительно соответствует реальности - а на 20% содержит галлюцинации.
Эту проблему обнаружили лет так 20 назад, и давно уже обсосали со всех сторон.
Вкратце, она формулируется так: "вы можете использовать формальные показатели для оценки прогресса/готовности, но как только от формальных показателей начинает зависеть оплата/повышение, люди найдут способ их фальсифицировать".
Учёт времени, потраченного на задачу - важен и нужен. Он позволяет руководителю (и вам!) оценить, какие задачи уже далеко продвинулись, а какие - конь не валялся.
Учёт времени на задачи - позволяет более-менее адекватно оценить и запланировать необходимое время на аналогичную задачу, когда она непременно возникнет в будущем.
Учет времени для задачи, разбитой на подзадачи - позволяет продемонстрировать менеджменту, что на задачу "сделать охрененно" действительно надо потратить 5000 часов, а не "ну, что там делать-то, за неделю соорудите быстренько".
Для непосредственного начальника, он таким образом может оценить, какова нормальная производительность разных сотрудников. И учесть при планировании.
Но - как только "часы на задачу" будут непосредственно учитываться для установки зарплаты, или для повышений - люди немедленно найдут способ фальсифицировать систему учёта.
Да не парьтесь вы! По статистике, 98% современных программистов работают над задачами, которые нафиг никому не нужны, и использоваться по делу никогда не будут.
И всем было бы лучше, если бы и не использовались никогда.
ИИ идеально закрывает потребность в написании такого кода.
Вообще-то это полная чушь. Вот у вас работает модель. Промпт идёт в виде текста, выводи - в виде текста. Где здесь модель может что-то "сделать" вообще?
Да блин, если у модели нет доступа на чтение к собственному исходному коду "снаружи" - думаете, она сможет в виде текста выдать те самые миллиарды параметров в выводе?
---------------
Реально, была решена с помощью этого долбанного ИИ следующая супер-мега-гига-задача:
"Напиши скрипт на bash, который запускает новый докер (вот пароли) и копирует туда вот этот кусок ПО".
Ага. Ничем не сложнее чем "напиши скрипт, который запускает докер, ставит туда следующие пакеты и копирует вот эту папку".
--------------
Саморепликация: это если бы нейросети сказали: "вот тебе консольный доступ (напрямую, текст который ты выдаёшь - уходит в bash), на машине установлен gcc и есть достаточно место. Скопируй туда себя". Доступа к исходной машине, разумеется, нет.
Угу. Давайте ИИ будет генерить сразу машинный код, чтобы человек-программист в принципе не мог понять, что он делает и в чём ошибка.
Кстати, подозреваю, что для ИИ генерация машинного кода вполне возможна, но будет проводиться через промежуточное высокоуровневое представление. Впрочем, "язык понятный ИИ" для человека также будет непонятен, поэтому практического смысла иметь не будет.
Прямо себе представляю ситуацию, когда вот у вас команда ИИ, "эффективный менеджер" над ней, и он интеративно пытается заставить команду ИИ создать сложный продукт, удовлетворяющий требованиям заказчика. И как обычно получается: чиним в одном месте, ломается в другом. И так неограниченно долго.
Лучше бы США на Марс слетали, вместо того, чтобы тратить два триллиона баксов на то, чтобы свергнуть талибов в Афганистане, и через два десятилетия вернуть их на место.
А уж если включить затраты на остальные войны, которые вёл за это время коллективный Запад - можно ещё и постоянную базу на Луне отгрохать.
Ну вот про C# то же самое говорили. Или про Java - что, кстати, почти оправдалось.
Реально встречаются Java-приложения, сложные - и работающие на любой платформе.
Вопрос же не в том, чтобы скомпилировать (этот вопрос давно закрыт с появлением llvm) - вопрос в том, чтобы предоставить разработке стандартное, универсальное API для работы. И чем оно более полное - тем сложнее и глючнее.
И да: если нужен "просто код" или "просто алгоритм" - так для этого можно или написать на интерпретируемом языке, или исходники предоставить. Все проблемы начинаются, когда хочется сделать "красиво". И интегрировано в нативное окружение.
Обращение по нулевому указателю С++ отлавливает, но в вашем примере его скорее всего просто не было. Параллельный доступ к дереву испортил его структуру, вероятно - часть памяти была утеряна, но обращения по нулевому указателю не было. "Испорченную" структуру данных типа зацикленного списка не отловит ничего, ну разве что кроме сторожевого таймера.
Рекомендую попробовать ваш пример для С++ со включённым анализатором времени исполнения - например, clang AddressSanitizer может отловить всякое.
Нет ни одной здравой причины перехватывать исключения, ну разве кроме случаев когда через исключение передают информацию о логической ошибке. Программа с ошибкой должна немедленно грохаться, чтобы эту ошибку можно было выявить и исправить. Максимум, что можно себе позволить: сохранить дополнительные данные в процессе завершения.
Вот именно! Практически в 100% случаев, попытка "продолжить работу после ошибки" - приводит к тому, что система становится не просто бесполезной, но - активно вредной.
Вот у вас нет памяти. Вы начинаете "обходить" ошибки выделения памяти, в результате - теряете данные, пользователь об этом не знает - и получает потерю или искажение пользовательских данных.
Например, разработчик текстового редактора (уровня OpenOffice/MS Word), если попробует "обходить" и "восстанавливаться" после проблем нехватки памяти - запросто может потерять часть документа. Или, например, вставленные рисунки. После чего пользователь этот документ сохраняет - и привет.
Практически единственный пример, когда "обход" ошибок выделения памяти оправдан - это если вы непосредственно по команде пользователя пытаетесь сделать что-то, требующее выделения большого-большого блока памяти, начинаете операцию с выделения памяти - и вот тут реально можно проверить, что память не выделена и операцию выполнить не удастся. И об этом удастся сообщить пользователю, т.к. свободная память ещё есть.
А вот если вы начали большую операцию, выделяете память мелкими кусочками по-объектно, и вот где-то в середине у вас обломалось выделение очередного мелкого объекта - вам кирдык.
Вы не сможете ни сообщить об этом пользователю, ни откатить операцию - так как памяти у вас вообще нет. А на сообщения и откат - сюрприз - нужна память.
Я такое проходил. Допустил утечку памяти, причём, малыми кусочками. За месяц непрерывной работы, память тупо кончилась вся. И дальше, так как программа именно была ориентирована на "продолжение работы" - начала терять функции интерфейса. Пункты из меню. Элементы интерфейса.
Что выглядело совершенным безумием для пользователя. Причём если бы она просто грохнулась - пользователь просто запустил бы её заново.
А, вот откуда появлется куча "программистов", постоянно использующих паттерн:
let data; try
{
data = this.getSomeData(); } catch(error)
{ data = this.getErrorData();
console.error(error); }
this.doSomething(data);
А ещё паттерн:
bool someFunc(Param * param)
{
if (nullptr == param) return false;
....
}
И ещё хорошо, если ошибку залогируют.
Возможно, если хорошо прищуриться, это может в каких-то редких случаях иметь смысл при разработке фронтенда на JS.
Но! Вот такой подход категорически, абсолютно недопустим при разработке абсолютно любых реально используемых для чего-то разумного продуктов.
Самый разумный подход: это при обнаружении ошибки, которую вы не знаете как можно обработать - немедленно паниковать с сохранением достаточной информации (где и почему) запаниковало.
Попытки продложить работу, если вы обнаружили не предусмотренную вашим алгоритмом ошибку - их необходимо категорически исключить. Продолжая работу при ошибке - вы а) сделаете хуже б) затрудните обнаружение и исправление ошибки.
Включите в ваш набор инструментов аналог макроса assert (я предпочитаю комбинацию verify()/halt())
который никогда не отключается,
в том числе в релизной сборке.
Активно применяйте его для проверки входных данных, выходных данных, возвращаемых значений и промежуточных условий/утверждений.
Подход "оборонительного программирования" - не означает, что вы должны паниковать и завершать работу, если пользователь указал для сохранения данных файл, не доступный на запись, или если сетевое соединение разорвалось.
Вы можете корректно и разумно обработать эти события? Обрабатывайте. Не можете или вам лень вот прямо сейчас писать код обработки? Ставьте verify().
Но вот если вам в функцию передали nullptr, и в спецификации функции не указано, что "вот этот параметр можно поставить null и поведение будет следующим ..." - паникуйте. Никогда, ни при каких условиях не надо пытаться "маскировать" ошибку.
Читать почту и отвечать на почту. А для того, чтобы ответить на почту - надо знать, что отвечать.
И да, есть такой небольшой нюанс: у нейросети нет отдельного входа для "данных снаружи" и "данных изнутри".
Их можно маркировать "данные присланные снаружи" и "внутренние данные" - но нейросеть технически никак не ограничена в том, чтобы эти данные не могла попутать.
Точно так же, как человек может забыться и в ответ на электронной письмо с незнакомого адреса ответить какой-нибудь конфеденциальной информацией. Типа: "ой, не подумал".
---------------
Теоретически, если у нейросети просто нет доступа к "закрытой" информации - а только к открытой - она не сможет её разгласить. Но тогда особого смысла в этой нейросети и нет.
То есть я правильно понимаю - вместо литературных текстов, системе глубокого обучения дали на вход 22 миллиона спецификаций ферментов и описания их свойств, а далее - для спецификации фермента предложили описать его свойства?
Охренительно. То есть модель никакого физического представляения о самом ферменте (и том, как он работает в огранизме) не имеет, но выдаёт "похожие на настоящие" описания?
Хайпожоры, что тут сказать.
Стартап нашёл в открытой прессе его описание, и решил, что уж они-то смогут реализовать отличную идею!
Ну или хотя бы финансирование привлечь...
В крайнем случае, будут продавать русским эти ядерные отходы, типа "переработка на аутсоурсе".
Угу. Они покупают комплектующие у американских компаний. А вот производят ли они эти комплектующие в США - или импортируют из Китая - это уже второй вопрос.
И есть большое подозрение, что на каком-то уровне резко выясняется, что "а вот это мы купили в Китае".
Первое, что делаешь, когда сервис не может что-то открыть/запустить/увидеть - отрубаешь SELinux. В большинстве случаев - помогает.
Самоё печальное, что даже в операционках, в которых SELinux поставляется включённым по умолчанию, пакеты установленные из штатного системного репозитария - могут нифига не устанавливать нужные им для функционирования права доступа. Даже такой стандарт, как апач.
А по поводу решения Торвальдса делать отдельную отключаемую приблуду - на самом деле, в этом он был абсолютно прав.
Реально, исторические права доступа в Юниксе - это тот разумный минимум, которым будет пользоваться 95%-98% пользователей. Достаточно просто и удобно, чтобы можно было пользоваться постоянно - и достаточно возможностей/функционала, чтобы решить практически все реальные задачи ограничения прав доступа.
Подход, который реализован в SELinux ( и в системе ограничения прав доступа в Windows ) - он продиктован идеей "давайте сделаем супер-пупер систему, пригодную для суперсекретной деятельности". По спецификации уродов из спецслужб США, которым абсолютно насрать на удобство использования, главное - чтобы "секьюрно".
В результате, 99% пользователей даже и не пытаются с этой системой разобраться. А значит, в принципе не пользуются. А если пользуются - то хрен его знает, не открыто ли там чего лишнего.
"Вся эта документация и проверка относительно десятков «корпоративных стандартов разработки», приемо-сдаточные испытания, проверка кибербезопасности, выкладвание в Реестр Российского ПО, проверка на 4-й уровень доверия ФСТЭК и куча другой бумагомарательной необходимой работы — в идеале будет делаться автоматически."
Вы понимаете, что это одна из проблем внедрения генерирующих нейронных сетей?
Ведь вся эта бумага, вся это "ненужна документация" и "стандарты кодирования" - они все сделаны не для того, чтобы испортить настроение разработчика. Это всё сделано для того, чтобы продуктом можно было нормально пользоваться и его развивать - человеку.
Если вы всё это отдаёте "нейросетям" - значит, можете с тем же успехом всё это просто выкинуть.
Даже хуже - отсутствие документации лучше, чем наличие бессмысленной сгенерированной документации. Которая выглядит почти как настоящая, и на 80% действительно соответствует реальности - а на 20% содержит галлюцинации.
Угу. И вывод какой замечательный - надо больше микрогридов, больше децентрализации, больше солнечных батарей и домашних аккумуляторов.
Ага, конечно. Больше солнечных батарей богу зелёной энергии к трону его!
Ага. Да вы опасный человек! Дай вам волю, так вы до ZMODEM додумаетесь!
То, что демонстрируют нынешние модели ИИ - это очень интересно, забавно и прикольно.
Но - реальная незначительная польза тут может быть только в индустрии развлечений и мошенничестве.
А, и ещё мы можем засрать интернет гигатоннами сгенерированной чуши, неотличимой без гигантских усилий от реальных фактов.
С практической точки зрения, человечеству имеет смысл вот эту всю хрень запретить напрочь.
И не потому, что "ИИ нас завоюет" или "убьёт всех человеков" - а потому, что ИИ потопит нашу цивилизацию под цунами мусорных данных.
Кстати, интернет-поисковики имеет смысл также уничтожить. По тем же причинам.
Эту проблему обнаружили лет так 20 назад, и давно уже обсосали со всех сторон.
Вкратце, она формулируется так: "вы можете использовать формальные показатели для оценки прогресса/готовности, но как только от формальных показателей начинает зависеть оплата/повышение, люди найдут способ их фальсифицировать".
Учёт времени, потраченного на задачу - важен и нужен. Он позволяет руководителю (и вам!) оценить, какие задачи уже далеко продвинулись, а какие - конь не валялся.
Учёт времени на задачи - позволяет более-менее адекватно оценить и запланировать необходимое время на аналогичную задачу, когда она непременно возникнет в будущем.
Учет времени для задачи, разбитой на подзадачи - позволяет продемонстрировать менеджменту, что на задачу "сделать охрененно" действительно надо потратить 5000 часов, а не "ну, что там делать-то, за неделю соорудите быстренько".
Для непосредственного начальника, он таким образом может оценить, какова нормальная производительность разных сотрудников. И учесть при планировании.
Но - как только "часы на задачу" будут непосредственно учитываться для установки зарплаты, или для повышений - люди немедленно найдут способ фальсифицировать систему учёта.
Да не парьтесь вы! По статистике, 98% современных программистов работают над задачами, которые нафиг никому не нужны, и использоваться по делу никогда не будут.
И всем было бы лучше, если бы и не использовались никогда.
ИИ идеально закрывает потребность в написании такого кода.
Вообще-то это полная чушь. Вот у вас работает модель. Промпт идёт в виде текста, выводи - в виде текста. Где здесь модель может что-то "сделать" вообще?
Да блин, если у модели нет доступа на чтение к собственному исходному коду "снаружи" - думаете, она сможет в виде текста выдать те самые миллиарды параметров в выводе?
---------------
Реально, была решена с помощью этого долбанного ИИ следующая супер-мега-гига-задача:
"Напиши скрипт на bash, который запускает новый докер (вот пароли) и копирует туда вот этот кусок ПО".
Ага. Ничем не сложнее чем "напиши скрипт, который запускает докер, ставит туда следующие пакеты и копирует вот эту папку".
--------------
Саморепликация: это если бы нейросети сказали: "вот тебе консольный доступ (напрямую, текст который ты выдаёшь - уходит в bash), на машине установлен gcc и есть достаточно место. Скопируй туда себя". Доступа к исходной машине, разумеется, нет.
Угу. Давайте ИИ будет генерить сразу машинный код, чтобы человек-программист в принципе не мог понять, что он делает и в чём ошибка.
Кстати, подозреваю, что для ИИ генерация машинного кода вполне возможна, но будет проводиться через промежуточное высокоуровневое представление. Впрочем, "язык понятный ИИ" для человека также будет непонятен, поэтому практического смысла иметь не будет.
Прямо себе представляю ситуацию, когда вот у вас команда ИИ, "эффективный менеджер" над ней, и он интеративно пытается заставить команду ИИ создать сложный продукт, удовлетворяющий требованиям заказчика. И как обычно получается: чиним в одном месте, ломается в другом. И так неограниченно долго.
Лучше бы США на Марс слетали, вместо того, чтобы тратить два триллиона баксов на то, чтобы свергнуть талибов в Афганистане, и через два десятилетия вернуть их на место.
А уж если включить затраты на остальные войны, которые вёл за это время коллективный Запад - можно ещё и постоянную базу на Луне отгрохать.
Не понял. А зачем для копирования массива организуем цикл?
В языке что, нет способа скопировать массив в одну строчку?
Ну вот про C# то же самое говорили. Или про Java - что, кстати, почти оправдалось.
Реально встречаются Java-приложения, сложные - и работающие на любой платформе.
Вопрос же не в том, чтобы скомпилировать (этот вопрос давно закрыт с появлением llvm) - вопрос в том, чтобы предоставить разработке стандартное, универсальное API для работы. И чем оно более полное - тем сложнее и глючнее.
И да: если нужен "просто код" или "просто алгоритм" - так для этого можно или написать на интерпретируемом языке, или исходники предоставить. Все проблемы начинаются, когда хочется сделать "красиво". И интегрировано в нативное окружение.
Обращение по нулевому указателю С++ отлавливает, но в вашем примере его скорее всего просто не было. Параллельный доступ к дереву испортил его структуру, вероятно - часть памяти была утеряна, но обращения по нулевому указателю не было. "Испорченную" структуру данных типа зацикленного списка не отловит ничего, ну разве что кроме сторожевого таймера.
Рекомендую попробовать ваш пример для С++ со включённым анализатором времени исполнения - например, clang AddressSanitizer может отловить всякое.
Нет ни одной здравой причины перехватывать исключения, ну разве кроме случаев когда через исключение передают информацию о логической ошибке. Программа с ошибкой должна немедленно грохаться, чтобы эту ошибку можно было выявить и исправить. Максимум, что можно себе позволить: сохранить дополнительные данные в процессе завершения.
Никто не мешает сделать это опцией, и собирать библиотеку по-разному для разных сценариев использования.