Skip to content

Instantly share code, notes, and snippets.

@ReSTARTR
Last active April 26, 2016 15:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ReSTARTR/1f5f2305e2f1a687c32bf618121adab5 to your computer and use it in GitHub Desktop.
Save ReSTARTR/1f5f2305e2f1a687c32bf618121adab5 to your computer and use it in GitHub Desktop.
Error handling idioms with pkg/errors

経緯

雑感

エラーの階層化って深くなることはあまりないだろうし、ライブラリの中でWrapされることも少ないだろう。

Causeで取れるのもCauserを満たす最後(最古)のエラーだけなので、あまり深くWrapすると意図せずハマりそう。

errors.Wrapされた階層が深くなる場合、hashicorp/errwrapのWalk()のような機能があると良さそう。

深くなる前の早い段階で適切に処理するのが一番ではあるけど。

関連

package main
import (
"fmt"
"github.com/pkg/errors"
"os"
)
type MyError struct {
Code int
}
func (e MyError) Error() string {
return fmt.Sprintf("It's my error (code: %d)", e.Code)
}
func (e MyError) IsExpected() bool {
return e.Code == 404
}
func f1() error {
return MyError{Code: 404}
}
func f2() error {
if err := f1(); err != nil {
return errors.Wrap(err, "error at f2")
}
return nil
}
func f3() error {
if err := f2(); err != nil {
return errors.Wrap(err, "error at f3")
}
return nil
}
func main() {
fmt.Println("Example of errors.Wrap ----")
err := f3()
errors.Fprint(os.Stderr, err)
/*
errors.go:34: error at f3
errors.go:27: error at f2
It's my error (code: 404)
*/
fmt.Println("Example of errors.Cause ----")
if ee, ok := errors.Cause(err).(MyError); ok {
if ee.IsExpected() {
errors.Fprint(os.Stderr, ee)
// It's my error (code: 404)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment