В Go есть стандартный подход к обработке ошибок через возврат значения типа error из функции. В отличие от языков с исключениями, в Go исключения (panic, recover) используются только для truly exceptional situations; для бизнес-логики следует использовать обычную ошибку.
Классический способ:
func doSomething() error { // ... return nil // или errors.New("some error") } err := doSomething() if err != nil { // обработка ошибки }
Вы можете создавать собственные типы ошибок для более подробного анализа:
type MyError struct { Code int Message string } func (e *MyError) Error() string { return fmt.Sprintf("(%d) %s", e.Code, e.Message) } err := &MyError{404, "not found"}
Типичная проверка конкретной ошибки:
if myErr, ok := err.(*MyError); ok && myErr.Code == 404 { // обработка ошибки 404 }
Можно ли сравнивать error с nil с помощью == в Go?
Ответ: Да, можно и нужно, чтобы проверить отсутствие ошибки. Но важно помнить: если error был обернут или создан с помощью ошибок, содержащих nil внутри структур, то сравнение может быть неверным. Например:
var err error = (*MyError)(nil) fmt.Println(err == nil) // false!
Ошибку делают потому, что интерфейс не равен nil, если его тип не nil, даже если значение внутри nil.
История
Микросервис занимался логированием ошибок через сравнение на nil. Один из разработчиков возвращал типизированную ошибку вроде (*MyError)(nil), не замечая, что это не эквивалентно nil (интерфейс не nil). В результате обработка ошибок перестала работать, и множество ложных алертов попали в метрики.
История
В проекте вместо передачи ошибки по цепочке, использовали panic для всех ошибок, считая это "чистым" способом. Это привело к падению приложения при каждом невалидном вводе пользователя, т.к. panic/recover не предназначены для потоковой бизнес-логики.
История
Ошибка была обернута несколько раз с помощью fmt.Errorf("some: %w", err), а при проверке на конкретный тип ошибки делали обычное сравнение, вместо использования errors.Is и errors.As. Это приводило к тому, что бизнес-логика не реагировала на кастомные типы ошибок, хотя те реально присутствовали внутри обернутой ошибки.