Главная » Хабрахабр » Повышаем информативность ошибок в Go – github.com/ztrue/tracerr

Повышаем информативность ошибок в Go – github.com/ztrue/tracerr

После многолетнего опыта работы с php и js, я привык иметь в ошибках стектрейс и смотреть на место, где произошла ошибка прямо из эррор-репорта. Пересев на Go пару лет назад, я был несколько удивлен, что в Go другие правила и нужно угадывать стектрейс по какой-нибудь строке типа `invalid character`. А если она произошла на проде и не известно, как ее воспроизвести, то это превращалось в целый аттракцион.

Поскольку я уверен, что не один от этого страдал, то сделал пакет, который умеет так:

golang error output

→ GitHub
Все, что он делает, это:

  1. Добавляет к ошибкам стектрейс.
  2. Отображает стектрейс и фрагменты исходников, где эта ошибка произошла (при наличии исходников, конечно).

Добавление стектрейса

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

// создать новую
err := tracerr.New("some error") // можно методом Errorf, который работает так же, как и fmt.Errorf
err := tracerr.Errorf("some error %d", num) // или обернуть существующую ошибку, добавив ей стектрейс
err = tracerr.Wrap(err)

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

Код может выглядеть как-то так:

func decodeFile(path string, data interface) error { b, err := ioutil.ReadFile(path) if err != nil { return tracerr.Wrap(err) } err = json.Unmarshal(b, data) // если err = nil, то останется nil return tracerr.Wrap(err)
}

Отображение стектрейса

После того, как ошибка через 100500 if err != nil { return err } вернется на Родину в main() (или там, где она обрабатывается), скорее всего Вы захотите ее отобразить или залогировать.
Для это есть несколько опций: все работают, как Print (выводит текст) или Sprint (возвращает текст):

1) Отобразить текст ошибки и стектрейс:

tracerr.Print(err)

2) Отобразить текст ошибки, стектрейс и фрагмент исходников (6 строк по дефолту):

tracerr.PrintSource(err)

3) То же, но в цвете, обычно более информативно:

tracerr.PrintSourceColor(err)

4) Можно передать параметром, сколько строк кода отобразить:

tracerr.PrintSource(err, 9)
tracerr.PrintSourceColor(err, 9)

5) Или передать 2 опциональных параметра, сколько до и сколько после строки с ошибкой отобразить:

tracerr.PrintSource(err, 5, 2)
tracerr.PrintSourceColor(err, 5, 2)

Вопросы

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

Есть дебаггер.
О: Это подходит не только для дебага, можно логировать ошибки с информацией о стектрейсе, и даже с фрагментами исходников, на проде, как по моему опыту, это существенно упростит потом эти ошибки разбирать. В: Это подходит только для дебага?

В: Есть супер пакет pkg/errors, почему не использовать его?
О: Есть, я сам его вполне использовал и рад, но он не подошел мне по этим причинам:
1) Там нет простого способа отобразить стектрейс сразу с исходниками.
2) При повторном оборачивании ошибки (например, на уровень выше), стектрейс затирается менее информативным.
3) При каждом оборачивании обязательно передавать дополнительный текст ошибки, что мне кажется некоторым оверхедом при написании/чтении кода.

Если Вам удобнее обрабатывать тысячи if err != nil { return err } каким-то другим способом — это Ваш выбор, конечно. В: В Go ошибки это не исключения и так делать вообще нельзя.
О: Согласен, в Go ошибки это не исключения. Вы можете оборачивать только те ошибки, которые обрабатываете как исключения.

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

В общем, надеюсь, этот пакет несколько облегчит Вашу гоферскую жизнь, буду рад любому фидбеку, спасибо.


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

PHP-Дайджест № 154 (9 – 21 апреля 2019)

В выпуске: Zend Framework переходит под крыло Linux Foundation, новости из PHP Internals, порция полезных инструментов, и многое другое. Свежая подборка со ссылками на новости и материалы. Приятного чтения! Новости и релизы PHP Internals Инструменты pinba-server/pinba-server — Простой pinba-сервер на ...

Язык Bosque — новый язык программирования от Microsoft

Языку дали название Bosque. Буквально несколько дней назад компания Microsoft представила публике новый язык программирования. Главная миссия дизайна языка — лучше быть богатым и здоровым, чем бедным и больным чтобы он был прост и понятен как для человека, так и ...