Я тримаю це просто.
Бібліотека має тип базового винятку, розширений від std ::: runtime_error (це з C ++ застосовується у відповідних випадках до інших мов). Цей виняток займає рядок повідомлення, щоб ми могли увійти; кожна точка кидка має унікальне повідомлення (як правило, з унікальним ідентифікатором).
Ось про це.
Примітка 1 : У ситуаціях, коли хтось, хто виловлює виняток, може виправити винятки та повторно розпочати дію. Я додам похідні винятки для речей, які потенційно можна однозначно виправити у віддаленому місці. Але це дуже рідко (Пам'ятайте, що ловець навряд чи буде близьким до точки кидка, тому виправити проблему буде важко (але все залежить від ситуації)).
Примітка 2 : Іноді бібліотека настільки проста, що не варто давати її власним винятком і виконуватиме std :: runtime_error. Важливо мати виключення лише в тому випадку, якщо можливість відрізнити його від std :: runtime_error може дати користувачеві достатньо інформації, щоб зробити щось з ним.
Примітка 3 : У межах класу я, як правило, віддаю перевагу кодам помилок (але вони ніколи не вийдуть через загальнодоступний API мого класу).
Дивлячись на ваші торгові операції
Я бачу компроміси:
Більше класів винятків може дозволяти дуже точним рівнем обробки помилок для користувачів API (схильних до конфігурації користувача чи помилок даних або файлів не знайдено)
Чи справді більше винятків дають точніший контроль над зерном? Постає питання, чи може дійсний код виправити помилку на основі винятку. Я впевнений, що є такі ситуації, і в цих випадках у вас повинен бути інший виняток. Але всі винятки, які ви перерахували вище, єдине корисне виправлення - це генерувати велике попередження та зупиняти програму.
Більш класи класів винятків дозволяють вбувати у виняток інформацію, пов’язану з помилками, а не просто рядкове повідомлення або код помилки
Це чудова причина для використання винятків. Але інформація повинна бути корисною людині, яка її кешує. Чи можуть вони використовувати інформацію для виконання деяких коригуючих дій? Якщо об'єкт є внутрішньою для вашої бібліотеки і не може бути використаний для впливу на будь-який API, то інформація є марною. Вам потрібно бути дуже конкретним, що викинута інформація має корисне значення для людини, яка може її вловити. Особа, яка її ловить, зазвичай знаходиться поза вашим загальнодоступним API, тому адаптуйте вашу інформацію, щоб вона могла використовуватися з речами у вашому загальнодоступному API.
Якщо все, що вони можуть зробити, це ввімкнути виняток, то краще просто викинути повідомлення про помилку, а не багато даних. Оскільки видовище зазвичай будує повідомлення про помилку з даними. Якщо ви будуєте повідомлення про помилку, то воно буде узгоджено для всіх виловлювачів, якщо ви дозволите ловець створити повідомлення про помилку, ви могли б отримати одну і ту ж помилку, повідомлену по-різному, залежно від того, хто дзвонить і ловить.
Менше винятків, але вбудований код помилки, який можна використовувати як пошук
Ви повинні визначити погоду, код помилки може бути змістовно використаний. Якщо це можливо, у вас повинен бути власний виняток. Інакше вашим користувачам тепер потрібно впроваджувати оператори перемикання всередині улову (що перемагає всю точку автоматичного оброблення улову).
Якщо він не може, то чому б не використати повідомлення про помилку за винятком (немає необхідності розділяти код і повідомлення, це болить шукати).
Повернення кодів помилок та прапорів безпосередньо з функцій (іноді неможливо з потоків)
Повернення кодів помилок є чудовим зсередини. Це дозволяє виправляти помилки там і потім, і ви повинні переконатися, що ви виправите всі коди помилок і врахуйте їх. Але витікати їх через ваш загальнодоступний API - погана ідея. Проблема полягає в тому, що програмісти часто забувають перевіряти стан помилок (принаймні, за винятком, неперевірена помилка змусить програму вийти з необробленої помилки, як правило, пошкодить усі ваші дані).
Реалізовано систему подій чи зворотних дзвінків після помилки (уникає розмотування стека)
Цей метод часто використовується спільно з іншими механізмами поводження з помилками (не як альтернатива). Подумайте про свою програму Windows. Користувач ініціює дію, вибравши пункт меню. Це генерує дію в черзі подій. Черга подій врешті-решт призначає потік для обробки дії. Нитка повинна керувати дією і врешті повернутися до пулу потоків і чекати іншого завдання. Тут виняток має бути зачеплений за основу ниткою із завданням. Результат вилучення виключення, як правило, призводить до події, що генерується для основного циклу, що в кінцевому підсумку призведе до відображення повідомлення про помилку користувачеві.
Але якщо ви не можете продовжувати перед винятком, стек буде розмотуватися (як мінімум, для потоку).