Documentation
¶
Overview ¶
Package err2 provides three main functionality:
- err2 package includes helper functions for error handling & stack tracing
- try package is for error checking
- assert package is for design-by-contract and preconditions
The traditional error handling idiom in Go is roughly akin to
if err != nil { return err }
which applied recursively.
The err2 package drives programmers to focus more on error handling rather than checking errors. We think that checks should be so easy that we never forget them. The CopyFile example shows how it works:
// CopyFile copies source file to the given destination. If any error occurs it
// returns error value describing the reason.
func CopyFile(src, dst string) (err error) {
// Add first error handler just to annotate the error properly.
defer err2.Returnf(&err, "copy %s %s", src, dst)
// Try to open the file. If error occurs now, err will be annotated and
// returned properly thanks to above err2.Returnf.
r := try.To1(os.Open(src))
defer r.Close()
// Try to create a file. If error occurs now, err will be annotated and
// returned properly.
w := try.To1(os.Create(dst))
// Add error handler to clean up the destination file. Place it here that
// the next deferred close is called before our Remove call.
defer err2.Handle(&err, func() {
os.Remove(dst)
})
defer w.Close()
// Try to copy the file. If error occurs now, all previous error handlers
// will be called in the reversed order. And final return error is
// properly annotated in all the cases.
try.To1(io.Copy(w, r))
// All OK, just return nil.
return nil
}
Error checks ¶
The try package 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 := try.To1(ioutil.ReadAll(r))
Note that try.ToX functions are as fast as if err != nil statements. Please see the try package documentation for more information about the error checks.
Stack Tracing ¶
err2 offers optional stack tracing. It's automatic. Just set the StackTraceWriter to the stream you want traces to be written:
err2.StackStraceWriter = os.Stderr // write stack trace to stderr or err2.StackStraceWriter = log.Writer() // stack trace to std logger
Error handling ¶
Package err2 relies on declarative control structures to achieve error and panic safety. In every function which uses err2 or try package for error-checking has to have at least one declarative error handler if it returns error value. If there are no error handlers and error occurs it panics. We think that panicking for the errors is much better than not checking errors at all. Nevertheless, if the call stack includes any err2 error handlers like err2.Handle the error is handled where the handler is saved to defer-stack. (defer is not lexically scoped)
err2 includes many examples to play with like previous CopyFile. Please see them for more information.
Example (CopyFile) ¶
package main
import (
"fmt"
"io"
"os"
"github.com/lainio/err2"
"github.com/lainio/err2/try"
)
func main() {
copyFile := func(src, dst string) (err error) {
defer err2.Returnf(&err, "copy %s %s", src, dst)
// These try package helpers are as fast as Check() calls which is as
// fast as `if err != nil {}`
r := try.To1(os.Open(src))
defer r.Close()
w := try.To1(os.Create(dst))
defer err2.Handle(&err, func() {
os.Remove(dst)
})
defer w.Close()
try.To1(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 Annotatew(prefix string, err *error)
- func Catch(f func(err error))
- func CatchAll(errorHandler func(err error), panicHandler func(v any))
- func CatchTrace(errorHandler func(err error))
- func Check(err error)
- func FilterTry(filter, err error) bool
- func Handle(err *error, handler func())
- func Return(err *error)
- func Returnf(err *error, format string, args ...any)
- func Returnw(err *error, format string, args ...any)
- func Try(args ...any) []any
- func TryEOF(err error) bool
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. Note! Deprecated, use try package.
var Bools _Bools
Bools is a helper variable to generated 'type wrappers' to make Try function as fast as Check. Note! Deprecated, use try package.
var Byte _Byte
Byte is a helper variable to generated 'type wrappers' to make Try function as fast as Check. Note! Deprecated, use try package.
var Bytes _Bytes
Bytes is a helper variable to generated 'type wrappers' to make Try function as fast as Check. Note! Deprecated, use try package.
var Empty _empty
Empty is deprecated. Use try.To functions instead. Empty is a helper variable to demonstrate how we could build 'type wrappers' to make Try function as fast as Check. Note! Deprecated, use try package.
var File _File
File is a helper variable to generated 'type wrappers' to make Try function as fast as Check. Note! Deprecated, use try package.
var Int _Int
Int is a helper variable to generated 'type wrappers' to make Try function as fast as Check. Note! Deprecated, use try package.
var Ints _Ints
Ints is a helper variable to generated 'type wrappers' to make Try function as fast as Check. Note! Deprecated, use try package.
var R _R
R is a helper variable to generated 'type wrappers' to make Try function as fast as Check. Note! Deprecated, use try package.
var Request _Request
Request is a helper variable to generated 'type wrappers' to make Try function as fast as Check. Note! Deprecated, use try package.
var Response _Response
Response is a helper variable to generated 'type wrappers' to make Try function as fast as Check. Note! Deprecated, use try package.
var StackStraceWriter io.Writer
StackStraceWriter allows to set automatic stack tracing.
err2.StackStraceWriter = os.Stderr // write stack trace to stderr or err2.StackStraceWriter = log.Writer() // stack trace to std logger
var StrStr _StrStr
StrStr is a helper variable to generated 'type wrappers' to make Try function as fast as Check. Note! Deprecated, use try package.
var String _String
String is a helper variable to generated 'type wrappers' to make Try function as fast as Check. Note! Deprecated, use try package.
var Strings _Strings
Strings is a helper variable to generated 'type wrappers' to make Try function as fast as Check. Note! Deprecated, use try package.
var W _W
W is a helper variable to generated 'type wrappers' to make Try function as fast as Check. Note! Deprecated, use try package.
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"
"github.com/lainio/err2/try"
)
func throw() (string, error) {
return "", fmt.Errorf("this is an ERROR")
}
func main() {
annotated := func() (err error) {
defer err2.Annotate("annotated", &err)
try.To1(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"
"github.com/lainio/err2/try"
)
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)
try.To1(throw())
return err
}
err := annotated()
fmt.Printf("%v", err)
}
Output: annotated 2nd: annotated 1st: this is an ERROR
func Annotatew ¶ added in v0.8.0
Annotatew 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.
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 ¶
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 is deprecated. Use try.To function instead. Check performs 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 FilterTry ¶ added in v0.7.0
FilterTry is deprecated. Use try.Is function instead. FilterTry performs filtered error check for the given argument. It's same as Check but before throwing an error it checks if error matches the filter. The return value false tells that there are no errors and true that filter is matched.
Example ¶
package main
import (
"bytes"
"fmt"
"io"
"github.com/lainio/err2"
)
func main() {
copyStream := func(src string) (s string, err error) {
defer err2.Returnf(&err, "copy stream %s", src)
in := bytes.NewBufferString(src)
tmp := make([]byte, 4)
var out bytes.Buffer
for n, err := in.Read(tmp); !err2.FilterTry(io.EOF, err); n, err = in.Read(tmp) {
out.Write(tmp[:n])
}
return out.String(), nil
}
str, err := copyStream("testing string")
if err != nil {
fmt.Println(err)
}
fmt.Println(str)
}
Output: testing string
func Handle ¶
func Handle(err *error, handler 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 is called only when err != nil.
Example ¶
package main
import (
"fmt"
"github.com/lainio/err2"
"github.com/lainio/err2/try"
)
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)
})
try.To1(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"
"github.com/lainio/err2/try"
)
func noThrow() (string, error) { return "test", nil }
func main() {
var err error
defer err2.Return(&err)
try.To1(noThrow())
}
func Returnf ¶
Returnf builds an error. It's similar to fmt.Errorf, but it's called only if error != nil. Note! It doesn't use %w to wrap the error. Use Returnw for that.
Example ¶
package main
import (
"fmt"
"github.com/lainio/err2"
"github.com/lainio/err2/try"
)
func throw() (string, error) {
return "", fmt.Errorf("this is an ERROR")
}
func main() {
annotated := func() (err error) {
defer err2.Returnf(&err, "annotated: %s", "err2")
try.To1(throw())
return err
}
err := annotated()
fmt.Printf("%v", err)
}
Output: annotated: err2: this is an ERROR
func Returnw ¶ added in v0.8.0
Returnw wraps an error. It's similar to fmt.Errorf, but it's called only if error != nil. Note! If you don't want to wrap the error use Returnf instead.
func Try ¶
Try is deprecated. Use try.To functions from try package instead. Try is as similar as proposed Go2 Try macro, but it's a function and it returns slice of interfaces. It has quite big performance penalty when compared to Check function.
func TryEOF ¶ added in v0.7.0
TryEOF is deprecated. Use try.IsEOF function instead. TryEOF checks errors but filters io.EOF from the exception handling and returns boolean which tells if io.EOF is present. See more info from FilterCheck.
Example ¶
package main
import (
"bytes"
"fmt"
"github.com/lainio/err2"
)
func main() {
copyStream := func(src string) (s string, err error) {
defer err2.Returnf(&err, "copy stream %s", src)
in := bytes.NewBufferString(src)
tmp := make([]byte, 4)
var out bytes.Buffer
for n, err := in.Read(tmp); !err2.TryEOF(err); n, err = in.Read(tmp) {
out.Write(tmp[:n])
}
return out.String(), nil
}
str, err := copyStream("testing string")
if err != nil {
fmt.Println(err)
}
fmt.Println(str)
}
Output: testing string
Types ¶
This section is empty.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package assert includes runtime assertion helpers.
|
Package assert includes runtime assertion helpers. |
|
internal
|
|
|
Package try is a package for try.ToX functions that implement the error checking.
|
Package try is a package for try.ToX functions that implement the error checking. |