Не варто так панікувати

В Golang спільноті існує правило стосовно того, що від використання panic необхідно відмовитися, особливо розробникам бібліотек. В цьому є розумне зерно, але будь-яке правило – це евристика, що базується на популярних анти-паттернах та історіях невдач, а не на поміркованому рішенні конкретної задачі. Подібні правила – це застареження для людей, що не мають звички замислюватись над тим, що роблять.

Panic attack of old man.

Використання panic необхідне у випадку, коли помилка не може бути опрацьована або проігнорована. Більшість помилок можуть бути опрацьовані, або проігноровані, але не всі.

Наприклад, якщо ми працюємо над web-застосунком і той не здатен сгенерувати HTML за певним шаблоном, то цю помилку ми можемо опрацювати і показати користувачу сторінку з 501 помилкою. Проте, що якщо ми можемо дещо перевірити під час ініціалізації застосунку (при його запуску, але до того, як він починає обробляти запити користувачів)?

Наприклад, під час ініціалізації ми можемо компілювати шаблони і заразом перевіряти чи вони коректні. Якщо шаблон не коректний і ми це можемо перевірити одразу при запуску застосунку, то навіщо нам такий зламаний застосунок? Це не виключна ситуація (сліпа точка у т.з. “логіці”), яку ми можемо записати до журналу, аби пізніше вирішити як її обробляти, а, наприклад, синтаксична/семантична помилка в DSL, на якому ми пишемо шаблони, що робить додаток, принаймні його частину, взагалі непридатною до використання.

Такий спосіб є непоганим компромісом, на який ми можемо піти у випадку досить бідної системи типів, що не дозволяє через типи позначити усі обмежання, аби перевірити їх т.з. фронтендом компілятора, перед беспосередньо компіляцією. Замість того, аби покладатися на фронтенд компілятора/систему типів, ми просто запускаємо додаток і він перевіряє власний стан на валідність.

Я вважаю, що використання panic цілком доцільне на старті застосунку, але ми дійсно маємо застосовувати їх у дуже крайніх випадках після ініціалізації. В Golang для ініціалізації є зручна семантика/контракт – функція init(). Якщо ми користуємося panic в init() – то це добре. Що стосується бібліотек, то варто вивчити ментальну модель, якою користуються їх автори та подивитися на приклади того, як самі автори їх використовують. 

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *