Оборачивание ошибок
Как правило, ошибка генерируется вне программы: в базе данных, сетевом соединении и т. д. Сообщения об ошибках, предоставленные из этих программ, усложняют поиск источника ошибки. Расширив ошибку с помощью дополнительной информации, ты получишь необходимый контекст для успешной отладки.
В следующем примере показано, как добавить информацию о контексте в ошибку, возвращаемую другой функцией, без этой информации ошибка выглядит запутанно.
WrappedError — это структура с двумя полями: контекстное сообщение в виде строки (string) и ошибка (error), о которой будет предоставлена дополнительная информация. Когда вызывается метод Error(), мы снова используем fmt.Sprintf для отображения контекстного сообщения, а затем и ошибки (fmt.Sprintf умеет неявно вызывать метод Error()).
Внутри main() мы создаем ошибку с помощью errors.New, а затем оборачиваем ее с помощью функции Wrap. Это позволяет нам указать, что эта ошибка была сгенерирована в main. Поскольку WrappedError также является ошибкой, мы могли бы обернуть другие структуры WrappedError — это отобразило бы цепочку, которая поможет отследить источник ошибки. С небольшой помощью стандартной библиотеки мы можем даже встроить в ошибки полное отслеживание стека.
Итак, теперь ты знаешь, как создавать разные типы ошибок для разных ситуаций. Этот навык пригодится тебе, например, в передаче нескольких фрагментов информации внутри ошибки или при реализации экспоненциальной выдержки. Хотя на первый взгляд механизмы обработки ошибок в Go могут показаться простоватыми, ты можешь добиться довольно сложной обработки через пользовательские ошибки — как в распространенных, так и в нетипичных ситуациях.
Для более подробного изучения темы рекомендуем тебе ознакомиться со следующими материалами: