Я полностью присоединюсь к ответу выше, просто хочу дополнить.
Замечу, что вы проверяете не то, что нужно, шиворот-навыворот. Проверять при приведении типов лучше конкретные типы. Т.е. мы получаем из функции ошибку в виде интерфейса error, а уже в проверке проверяем её на наш кастомный тип MyError. Поэтому желательно (не обязательно) не проверять переменную ошибки в той же функции, где вы её создали, а возвращать откуда-то и уже тогда проверять на ошибку.
К тому же, если у вас вопросы по этой теме, я настоятельно хочу порекомендовать правильно использовать кастомные типы ошибок, и даже если указатель на ваш кастомный тип ошиьбки равен nil, то ни в коем случае не возвращайте сам этот указатель, а возвращайте буквально nil. Так вы избавитесь от тысяч выстрелов себе в ногу.
package main
import (
"fmt"
)
type MyError struct {
Message string
}
func (e MyError) Error() string {
return e.Message
}
func main() {
// Возвращаем из функции нашу кастомную ошибку, но в виде интерфейса error
err := foo()
if err == nil {
fmt.Println("Нет ошибки")
// И теперь тут приводим error к нашему типу MyError и проверяем
} else if myErr, ok := err.(MyError); ok {
fmt.Printf("Ура! Нужный нам тип ошибки: %v\n", myErr.Message)
} else {
fmt.Println("Какой-то другой тип ошибки:", err)
}
// Проверка одной из "подстав" Go
err = bad()
if err != nil {
fmt.Println("Упс... Как так... Не nil...")
} else {
fmt.Println("Должно вывестись это, но не выводится...")
}
err = good()
if err != nil {
fmt.Println("Это не должно выводиться, всё верно.")
} else {
fmt.Println("Ошибки нет, всё верно.")
}
}
func foo() error {
err := MyError{"Ой! Ошибка MyError!"}
// err := fmt.Errorf("Ой! Обычная ошибка!")
// var err error = nil
return err
}
func bad() error {
var p *MyError = nil // Вроде же nil, но не работает....
// p = &MyError{"Ой!"} // Пробуем создать ошибку, и всё работает.
if p == nil {
fmt.Println("Ну nil же-ж... Должно же-ж работать", p)
}
return p
}
func good() error {
// return MyError{"Ой!"}
// Буквально пишем "nil", никаких указателей, которые равны nil, это прямой выстрел в ногу
return nil
}
https://go.dev/play/p/2YcWcH9oqel