Documentation ¶
Overview ¶
Package err2 provides simple helper functions for Go's error handling.
The traditional error handling idiom in Go is roughly akin to
if err != nil { return err }
which applied recursively. That leads to code smells: redundancy, noise&verbose, or suppressed checks. The err2 package drives programmers more to focus on error handling rather than checking errors. We think that checks should be so easy (help of the declarative control structures) that we never forget them.
err2.Try(io.Copy(w, r))
Error checks ¶
The err2 provides convenient helpers to check the errors. For example, instead of
b, err := ioutil.ReadAll(r) if err != nil { return err }
we can write
b := err2.Bytes.Try(ioutil.ReadAll(r))
but not without the handler.
Error handling ¶
Package err2 relies on error handlers. In every function which uses err2 for error-checking has to have at least one error handler. If there are no error handlers and error occurs it panics. Panicking for the errors during the development is better than not checking the error at all.
The handler for the previous sample is
defer err2.Return(&err)
which is the helper handler for cases that don't annotate errors. err2.Handle is a helper function to add needed error handlers to defer stack. In most real-world cases, we have multiple error checks and only one or just a few error handlers per function.
Example (CopyFile) ¶
package main import ( "fmt" "io" "os" "github.com/lainio/err2" ) func main() { copyFile := func(src, dst string) (err error) { defer err2.Returnf(&err, "copy %s %s", src, dst) // These helpers are as fast as Check() calls r := err2.File.Try(os.Open(src)) defer r.Close() w := err2.File.Try(os.Create(dst)) defer err2.Handle(&err, func() { os.Remove(dst) }) defer w.Close() err2.Empty.Try(io.Copy(w, r)) return nil } err := copyFile("/notfound/path/file.go", "/notfound/path/file.bak") if err != nil { fmt.Println(err) } }
Output: copy /notfound/path/file.go /notfound/path/file.bak: open /notfound/path/file.go: no such file or directory
Index ¶
- Variables
- func Annotate(prefix string, err *error)
- func Catch(f func(err error))
- func CatchAll(errorHandler func(err error), panicHandler func(v interface{}))
- func CatchTrace(errorHandler func(err error))
- func Check(err error)
- func Handle(err *error, f func())
- func Return(err *error)
- func Returnf(err *error, format string, args ...interface{})
- func Try(args ...interface{}) []interface{}
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var Bool _Bool
Bool is a helper variable to generated 'type wrappers' to make Try function as fast as Check.
var Bools _Bools
Bools is a helper variable to generated 'type wrappers' to make Try function as fast as Check.
var Byte _Byte
Byte is a helper variable to generated 'type wrappers' to make Try function as fast as Check.
var Bytes _Bytes
Bytes is a helper variable to generated 'type wrappers' to make Try function as fast as Check.
var Empty _empty
Empty is a helper variable to demonstrate how we could build 'type wrappers' to make Try function as fast as Check.
var File _File
File is a helper variable to generated 'type wrappers' to make Try function as fast as Check.
var Int _Int
Int is a helper variable to generated 'type wrappers' to make Try function as fast as Check.
var Ints _Ints
Ints is a helper variable to generated 'type wrappers' to make Try function as fast as Check.
var R _R
R is a helper variable to generated 'type wrappers' to make Try function as fast as Check.
var Request _Request
Request is a helper variable to generated 'type wrappers' to make Try function as fast as Check.
var Response _Response
Response is a helper variable to generated 'type wrappers' to make Try function as fast as Check.
var StrStr _StrStr
StrStr is a helper variable to generated 'type wrappers' to make Try function as fast as Check.
var String _String
String is a helper variable to generated 'type wrappers' to make Try function as fast as Check.
var Strings _Strings
Strings is a helper variable to generated 'type wrappers' to make Try function as fast as Check.
var URL _URL
URL is a helper variable to generated 'type wrappers' to make Try function as fast as Check.
var W _W
W is a helper variable to generated 'type wrappers' to make Try function as fast as Check.
Functions ¶
func Annotate ¶
Annotate is for annotating an error. It's similar to Returnf but it takes only two arguments: a prefix string and a pointer to error. It adds ": " between the prefix and the error text automatically.
Example ¶
package main import ( "fmt" "github.com/lainio/err2" ) func throw() (string, error) { return "", fmt.Errorf("this is an ERROR") } func main() { annotated := func() (err error) { defer err2.Annotate("annotated", &err) err2.Try(throw()) return err } err := annotated() fmt.Printf("%v", err) }
Output: annotated: this is an ERROR
Example (DeferStack) ¶
package main import ( "fmt" "github.com/lainio/err2" ) func throw() (string, error) { return "", fmt.Errorf("this is an ERROR") } func main() { annotated := func() (err error) { defer err2.Annotate("annotated 2nd", &err) defer err2.Annotate("annotated 1st", &err) err2.Try(throw()) return err } err := annotated() fmt.Printf("%v", err) }
Output: annotated 2nd: annotated 1st: this is an ERROR
func Catch ¶
func Catch(f func(err error))
Catch is a convenient helper to those functions that doesn't return errors. Go's main function is a good example. Note! There can be only one deferred Catch function per non error returning function. See Handle for more information.
func CatchAll ¶
func CatchAll(errorHandler func(err error), panicHandler func(v interface{}))
CatchAll is a helper function to catch and write handlers for all errors and all panics thrown in the current go routine.
func CatchTrace ¶
func CatchTrace(errorHandler func(err error))
CatchTrace is a helper function to catch and handle all errors. It recovers a panic as well and prints its call stack. This is preferred helper for go workers on long running servers.
func Check ¶
func Check(err error)
Check performs the error check for the given argument. If the err is nil, it does nothing. According the measurements, it's as fast as if err != nil {return err} on happy path.
func Handle ¶
func Handle(err *error, f func())
Handle is for adding an error handler to a function by defer. It's for functions returning errors them self. For those functions that doesn't return errors there is a Catch function. Note! The handler function f is called only when err != nil.
Example ¶
package main import ( "fmt" "github.com/lainio/err2" ) func throw() (string, error) { return "", fmt.Errorf("this is an ERROR") } func main() { doSomething := func(a, b int) (err error) { defer err2.Handle(&err, func() { err = fmt.Errorf("error with (%d, %d): %v", a, b, err) }) err2.Try(throw()) return err } err := doSomething(1, 2) fmt.Printf("%v", err) }
Output: error with (1, 2): this is an ERROR
func Return ¶
func Return(err *error)
Return is same as Handle but it's for functions which don't wrap or annotate their errors. If you want to annotate errors see Annotate for more information.
Example ¶
package main import ( "github.com/lainio/err2" ) func noThrow() (string, error) { return "test", nil } func main() { var err error defer err2.Return(&err) err2.Try(noThrow()) }
Output:
func Returnf ¶
Returnf wraps an error. It's similar to fmt.Errorf, but it's called only if error != nil.
Example ¶
package main import ( "fmt" "github.com/lainio/err2" ) func throw() (string, error) { return "", fmt.Errorf("this is an ERROR") } func main() { annotated := func() (err error) { defer err2.Returnf(&err, "annotated: %s", "err2") err2.Try(throw()) return err } err := annotated() fmt.Printf("%v", err) }
Output: annotated: err2: this is an ERROR
Types ¶
This section is empty.