I want to create hierarchical errors in Go. Can we achieve this in Go ? For an example, I have following two errors.
type Error1 struct {
reason string
cause error
}
func (error1 Error1) Error() string {
if error1.cause == nil || error1.cause.Error() == "" {
return fmt.Sprintf("[ERROR]: %s\n", error1.reason)
} else {
return fmt.Sprintf("[ERROR]: %s\nCaused By: %s\n", error1.reason, error1.cause)
}
}
type Error2 struct {
reason string
cause error
}
func (error2 Error2) Error() string {
if error2.cause == nil || error2.cause.Error() == "" {
return fmt.Sprintf("[ERROR]: %s\n", error2.reason)
} else {
return fmt.Sprintf("[ERROR]: %s\nCause: %s", error2.reason, error2.cause)
}
}
I want to have an error type CommonError
which consists of two sub-types, Error1
and Error1
, so that I can do the following.
func printType(param error) {
switch t := param.(type) {
case CommonError:
fmt.Println("Error1 or Error 2 found")
default:
fmt.Println(t, " belongs to an unidentified type")
}
}
Is there a way to achieve this ?
Edit:
In the type switch we can use multiple errors like this:
case Error1, Error2:
but When I have a larger number of errors, or when I need some abstraction for the errors inside a module, this approach won't be the best one.
You may list multiple types in a case
, so this will do what you want:
switch t := param.(type) {
case Error1, Error2:
fmt.Println("Error1 or Error 2 found")
default:
fmt.Println(t, " belongs to an unidentified type")
}
Testing it:
printType(Error1{})
printType(Error2{})
printType(errors.New("other"))
Output (try it on the Go Playground):
Error1 or Error 2 found
Error1 or Error 2 found
other belongs to an unidentified type
If you want to "group" the errors, another solution is to create a "marker" interface:
type CommonError interface {
CommonError()
}
Which Error1
and Error2
must implement:
func (Error1) CommonError() {}
func (Error2) CommonError() {}
And then you can do:
switch t := param.(type) {
case CommonError:
fmt.Println("Error1 or Error 2 found")
default:
fmt.Println(t, " belongs to an unidentified type")
}
Testing it with the same, output is the same. Try it on the Go Playground.
If you want to restrict CommonError
s to be "true" errors, also embed the error
interface:
type CommonError interface {
error
CommonError()
}