Reputation: 19353
I am trying to create a custom error in Go such that I can create new instances of that error with a custom message, and then handle that specific type of error. However, when I try to do this, then my overridden errors.Is()
is not being executed. Here is my code:
package main
import (
"fmt"
"errors"
)
type Error struct {
Message string
Code int
}
func (e *Error) Error() string {
return e.Message
}
func (e Error) Is(target Error) bool {
// This is never printed - this method never excutes for some reason
fmt.Println("compared!")
return e.Code == target.Code
}
var NotFoundError *Error = &Error{Code: 404, Message: "The page was not found"}
func NewError(errorType *Error, message string) error {
rc := *errorType
rc.Message = message
return &rc
}
func FetchImage() error {
return NewError(NotFoundError, "That image is gone")
}
func main() {
err := FetchImage()
// Returns false
fmt.Println(errors.Is(err, NotFoundError))
}
In this case, the call to errors.Is()
returns false. However, even though I have supplied my own Is() function, that function is not being called at all. That is, the string "compared!"
is never printed.
Why isn't my Is() function working as desired?
Upvotes: 3
Views: 8319
Reputation: 3484
You can use this:
package main
import (
"fmt"
)
type Error struct {
Message string
Code int
}
func (e *Error) Error() string {
return e.Message
}
func (e *Error) Is(target Error) bool {
// This is now printed
fmt.Println("compared!")
return e.Code == target.Code
}
var NotFoundError Error = Error{Code: 404, Message: "The page was not found"}
func NewError(errorType Error, message string) Error {
rc := errorType
rc.Message = message
return rc
}
func FetchImage() Error {
return NewError(NotFoundError, "That image is gone")
}
func main() {
err := FetchImage()
// Now it returns true
fmt.Println(err.Is(NotFoundError))
}
Upvotes: 0
Reputation: 5388
type Error struct {
Message string
Code int
}
func (e *Error) Error() string {
return e.Message
}
func (e *Error) Is(tgt error) bool {
// This is never printed - this method never excutes for some reason
fmt.Println("compared!")
target, ok := tgt.(*Error)
if !ok{
return false
}
return e.Code == target.Code
}
Your Error struct does not implement Is
method correctly, the parameter should be error
not Error
.
See in action:
https://play.golang.org/p/vRQndE9ZRuH
Upvotes: 7