Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni
🤖🚫 AI-free content. This post is 100% written by a human, as is everything on my blog. Enjoy!07.02.2025
Особливості помилок в Go: квазістектрейс
Вже пробачте, що я про Go зарядив (спойлер: завтра буде ще й оголошення невеличкого проєкту на Go), але сьогодні усвідомив один цікавий аспект. Цікавий скоріше тим, хто на Go не пише.
В Go помилка — це, в першому наближенні, так званий “таврований рядок”. Тобто зміст помилки — це рядок, але належність до типу error
чітко відрізняє її від “просто рядка”. У звичайних помилок немає більше нічого.
(Зокрема, в error
немає детальної типізації (ну як, вона може бути, бо error
- це тільки інтерфейс, але це буде нестандартно.) Щоб впізнати потрібну помилку, її роблять константою, та порівнюють за значенням.)
Також в error
немає стектрейсу (є бібліотеки, які його додають, але не загально прийнятні.) Але замість стектрейсу, в Go є загортання помилок. Коли вам повертають помилку, традиційно функцією fmt.Errorf додають до неї власну інформацію.
res, err := http.Request(myURL)
if err != nil {
return fmt.Errorf("loading URL failed: %w", err)
}
На верхньому рівні отримуємо щось на кшталт: failed to calculate balance: failed to load user: database request failed: io timeout
. Так виглядає типова помилка у Go. Та ось сьогодні збагнув, що це ж той самий стектрейс! Тільки ручної роботи. Можна грепати його частини та знайти, звідки вони.
З першого погляду, незрозуміла поробка. Але я знайшов пару переваг, порівняно зі стектрейсами. По-перше, такий загорнутий рядок відносно компактний, що важливо для логування. По-друге, стректрейси псуються при рівночасності (класична проблема інших мов), а загортання помилок — ні, його й з рівночасністю можна робити так, як зручно.
Власне, тому важливо завжди загортати помилки. Навіть є лінтер wrapcheck, який на це перевіряє.