Пользовательские ошибки
В этой теме мы разберем:
-
интерфейс error;
-
создание пользовательской ошибки и сбор подробной информации о ней;
-
утверждения типа и пользовательские ошибки;
-
оборачивание ошибок.
Интерфейс error
В стандартной библиотеке Go есть два метода для создания ошибок — errors.New и fmt.Errorf. Но иногда этих двух механизмов недостаточно, чтобы правильно собрать и отчитаться по ошибкам. Например, это бывает при обработке сложных ошибок для пользователей и при сборе информации по отладке.
Чтобы продуктивно обработать эту более сложную информацию, можно использовать тип интерфейса error из стандартной библиотеки.
Его синтаксис выглядит так, как показано на скриншоте.
Пакет builtin определяет error как интерфейс с единым методом Error(), который возвращает сообщение об ошибке в виде строки. Реализуя этот метод, мы можем изменить любой тип в пользовательскую ошибку.
Создание пользовательской ошибки
Давай попробуем запустить следующий пример, чтобы увидеть, как это работает.
Самое время протестировать код!
Мы получим такой вывод.
Мы создали новый пустой тип структуры MyError и определили в нем метод Error(). Метод Error() возвращает строку boom.
В main() мы вызываем функцию sayHello, которая возвращает пустую строку и новый экземпляр MyError. Поскольку sayHello всегда будет возвращать ошибку, вызов fmt.Println в теле оператора if в main() всегда будет выполняться. Затем fmt.Println выводит короткий строчный префикс unexpected error: вместе с экземпляром MyError, содержащимся в переменной err.
Обрати внимание, что вызывать Error() напрямую не нужно, поскольку пакет fmt может автоматически определять реализацию error. Он вызывает Error() прозрачно, чтобы получить строку boom и объединяет ее со строкой префикса unexpected error: err:.
Сбор подробной информации в пользовательской ошибке
Иногда пользовательская ошибка является наиболее простым способом сбора подробной информации об ошибке. Допустим, мы хотим собрать код состояния ошибок, вызванных HTTP-запросом. Чтобы увидеть реализацию ошибки, которая сделает это, запусти следующую программу.
Здесь мы создали новый экземпляр RequestError и предоставили код состояния и ошибку через функцию errors.New из стандартной библиотеки. После этого мы вывели ее с помощью fmt.Println, как в предыдущем примере.
Метод Error() из RequestError использует функцию fmt.Sprintf, чтобы составить строку на основе информации, полученной во время создания ошибки.