Documentation ¶
Overview ¶
Shorter error handling in Go. Supports two styles:
* Like the rejected "try" proposal (https://golang.org/design/32437-try-builtin).
* Exception-based.
Uses a combination of `defer` and panics to make code SIGNIFICANTLY shorter, at an acceptable runtime cost. Automatically ensures stacktraces via "github.com/pkg/errors". You can choose to keep `error` in signatures and use explicit "try", or drop `error` from signatures and use exceptions.
See `readme.md` and examples.
Index ¶
- func Bool(val bool, err error) bool
- func BoolSlice(val []bool, err error) []bool
- func Byte(val byte, err error) byte
- func ByteSlice(val []byte, err error) []byte
- func Catch(fun func()) (err error)
- func CatchOnly(test func(error) bool, fun func()) (err error)
- func Caught(fun func()) bool
- func CaughtOnly(test func(error) bool, fun func()) bool
- func Complex128(val complex128, err error) complex128
- func Complex128Slice(val []complex128, err error) []complex128
- func Complex64(val complex64, err error) complex64
- func Complex64Slice(val []complex64, err error) []complex64
- func Detail(msg string)
- func DetailOnly(test func(error) bool, msg string)
- func DetailOnlyf(test func(error) bool, msg string, args ...interface{})
- func Detailf(msg string, args ...interface{})
- func Err(val interface{}) error
- func Fail(fun func(error))
- func Float32(val float32, err error) float32
- func Float32Slice(val []float32, err error) []float32
- func Float64(val float64, err error) float64
- func Float64Slice(val []float64, err error) []float64
- func HasStack(err error) bool
- func Ignore()
- func IgnoreOnly(test func(error) bool)
- func Ignoring(fun func())
- func IgnoringOnly(test func(error) bool, fun func())
- func Int(val int, err error) int
- func Int16(val int16, err error) int16
- func Int16Slice(val []int16, err error) []int16
- func Int32(val int32, err error) int32
- func Int32Slice(val []int32, err error) []int32
- func Int64(val int64, err error) int64
- func Int64Slice(val []int64, err error) []int64
- func Int8(val int8, err error) int8
- func Int8Slice(val []int8, err error) []int8
- func IntSlice(val []int, err error) []int
- func Interface(val interface{}, err error) interface{}
- func InterfaceSlice(val []interface{}, err error) []interface{}
- func Ok(fun func())
- func Rec(ptr *error)
- func RecChan(errChan chan<- error)
- func RecOnly(ptr *error, test func(error) bool)
- func RecWith(fun func(error))
- func RecWithMessage(ptr *error, msg string)
- func RecWithMessagef(ptr *error, pattern string, args ...interface{})
- func Rune(val rune, err error) rune
- func RuneSlice(val []rune, err error) []rune
- func String(val string, err error) string
- func StringSlice(val []string, err error) []string
- func To(err error)
- func Trace()
- func Trans(fun func(error) error)
- func Transing(trans func(error) error, fun func())
- func Uint(val uint, err error) uint
- func Uint16(val uint16, err error) uint16
- func Uint16Slice(val []uint16, err error) []uint16
- func Uint32(val uint32, err error) uint32
- func Uint32Slice(val []uint32, err error) []uint32
- func Uint64(val uint64, err error) uint64
- func Uint64Slice(val []uint64, err error) []uint64
- func Uint8(val uint8, err error) uint8
- func Uint8Slice(val []uint8, err error) []uint8
- func UintSlice(val []uint, err error) []uint
- func Uintptr(val uintptr, err error) uintptr
- func UintptrSlice(val []uintptr, err error) []uintptr
- func WithMessage(ptr *error, msg string)
- func WithMessagef(ptr *error, pattern string, args ...interface{})
- func WithStack(err error) error
- type Val
Examples ¶
- Bool
- BoolSlice
- Byte
- ByteSlice
- Catch
- CatchOnly
- Caught
- CaughtOnly
- Complex128
- Complex128Slice
- Complex64
- Complex64Slice
- Detail
- DetailOnly
- DetailOnlyf
- Detailf
- Fail
- Float32
- Float32Slice
- Float64
- Float64Slice
- Ignore
- IgnoreOnly
- Ignoring
- IgnoringOnly
- Int
- Int16
- Int16Slice
- Int32
- Int32Slice
- Int64
- Int64Slice
- Int8
- Int8Slice
- IntSlice
- Interface
- InterfaceSlice
- Ok
- Rec
- RecChan
- RecOnly
- RecWith
- RecWithMessage
- RecWithMessagef
- Rune
- RuneSlice
- String
- StringSlice
- To
- Trace
- Trans
- Transing
- Uint
- Uint16
- Uint16Slice
- Uint32
- Uint32Slice
- Uint64
- Uint64Slice
- Uint8
- Uint8Slice
- UintSlice
- Uintptr
- UintptrSlice
- WithMessage
- WithMessagef
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Bool ¶
A "try" function that takes and returns a value of type `bool`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (bool, error) { return true, nil } fmt.Println(try.Bool(someFunc())) }
Output: true
func BoolSlice ¶
A "try" function that takes and returns a value of type `[]bool`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]bool, error) { return []bool{true}, nil } fmt.Println(try.BoolSlice(someFunc())) }
Output: [true]
func Byte ¶
A "try" function that takes and returns a value of type `byte`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (byte, error) { return 255, nil } fmt.Println(try.Byte(someFunc())) }
Output: 255
func ByteSlice ¶
A "try" function that takes and returns a value of type `[]byte`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]byte, error) { return []byte{255}, nil } fmt.Println(try.ByteSlice(someFunc())) }
Output: [255]
func Catch ¶ added in v0.1.2
func Catch(fun func()) (err error)
Converts a panic to an error, idempotently adding a stacktrace.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { someFunc := func() { try.To(errors.New(`failure A`)) // Will panic. try.To(errors.New(`failure B`)) // Not executed; would panic. try.To(nil) // Not executed; would not panic. } err := try.Catch(someFunc) fmt.Println(err) }
Output: failure A
func CatchOnly ¶ added in v0.1.2
Converts a panic to an error, if the error satisfies the provided test. Otherwise re-panics. Idempotently adds a stacktrace.
Example ¶
package main import ( "fmt" "os" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { isErrNoFile := func(err error) bool { return errors.Is(err, os.ErrNotExist) } maybeRead := func() { fmt.Println(try.ByteSlice(os.ReadFile(`non-existent-file`))) } err := try.CatchOnly(isErrNoFile, maybeRead) fmt.Println(err) }
Output: open non-existent-file: no such file or directory
func Caught ¶ added in v0.1.2
func Caught(fun func()) bool
Shortcut for `Catch() != nil`. Useful when you want to handle all errors while ignoring their content.
Example ¶
package main import ( "fmt" "os" "github.com/mitranim/try" ) func main() { maybeRead := func() { fmt.Println(try.ByteSlice(os.ReadFile(`non-existent-file`))) } fmt.Println(try.Caught(maybeRead)) }
Output: true
func CaughtOnly ¶ added in v0.1.4
Shortcut for `CatchOnly() != nil`. Useful when you want to handle a specific error while ignoring its content.
Example ¶
package main import ( "fmt" "os" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { isErrNoFile := func(err error) bool { return errors.Is(err, os.ErrNotExist) } maybeRead := func() { fmt.Println(try.ByteSlice(os.ReadFile(`non-existent-file`))) } fmt.Println(try.CaughtOnly(isErrNoFile, maybeRead)) }
Output: true
func Complex128 ¶
func Complex128(val complex128, err error) complex128
A "try" function that takes and returns a value of type `complex128`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (complex128, error) { return 255, nil } fmt.Println(try.Complex128(someFunc())) }
Output: (255+0i)
func Complex128Slice ¶
func Complex128Slice(val []complex128, err error) []complex128
A "try" function that takes and returns a value of type `[]complex128`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]complex128, error) { return []complex128{255}, nil } fmt.Println(try.Complex128Slice(someFunc())) }
Output: [(255+0i)]
func Complex64 ¶
A "try" function that takes and returns a value of type `complex64`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (complex64, error) { return 255, nil } fmt.Println(try.Complex64(someFunc())) }
Output: (255+0i)
func Complex64Slice ¶
A "try" function that takes and returns a value of type `[]complex64`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]complex64, error) { return []complex64{255}, nil } fmt.Println(try.Complex64Slice(someFunc())) }
Output: [(255+0i)]
func Detail ¶ added in v0.1.2
func Detail(msg string)
Must be deferred. Wraps non-nil panics, prepending the error message and idempotently adding a stacktrace.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { someFunc := func() { defer try.Detail(`failed to X`) try.To(errors.New(`failure A`)) // Will be wrapped. try.To(errors.New(`failure B`)) // Not executed; would panic. try.To(nil) // Not executed; would not panic. } err := try.Catch(someFunc) fmt.Println(err) }
Output: failed to X: failure A
func DetailOnly ¶ added in v0.1.3
Must be deferred. Wraps non-nil panics, prepending the error message, ONLY if they satisfy the provided test. Idempotently adds a stacktrace to all panics.
Example ¶
package main import ( "fmt" "os" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { isErrNoFile := func(err error) bool { return errors.Is(err, os.ErrNotExist) } someFunc := func() { defer try.DetailOnly(isErrNoFile, `file not found`) _ = try.ByteSlice(os.ReadFile(`non-existent-file`)) } err := try.Catch(someFunc) fmt.Println(err) }
Output: file not found: open non-existent-file: no such file or directory
func DetailOnlyf ¶ added in v0.1.3
Must be deferred. Wraps non-nil panics, prepending the error message, ONLY if they satisfy the provided test. Idempotently adds a stacktrace to all panics.
Example ¶
package main import ( "fmt" "os" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { isErrNoFile := func(err error) bool { return errors.Is(err, os.ErrNotExist) } someFunc := func() { const name = `non-existent-file` defer try.DetailOnlyf(isErrNoFile, `file %q not found`, name) _ = try.ByteSlice(os.ReadFile(name)) } err := try.Catch(someFunc) fmt.Println(err) }
Output: file "non-existent-file" not found: open non-existent-file: no such file or directory
func Detailf ¶ added in v0.1.2
func Detailf(msg string, args ...interface{})
Must be deferred. Wraps non-nil panics, prepending the error message and idempotently adding a stacktrace.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { someFunc := func() { defer try.Detailf(`failed to %v`, `X`) try.To(errors.New(`failure A`)) // Will be wrapped. try.To(errors.New(`failure B`)) // Not executed; would panic. try.To(nil) // Not executed; would not panic. } err := try.Catch(someFunc) fmt.Println(err) }
Output: failed to X: failure A
func Err ¶
func Err(val interface{}) error
Converts an arbitrary value to an error. Should be used with `recover()`:
err := Err(recover())
Caution: `recover()` works ONLY when called DIRECTLY inside a deferred function. When called ANYWHERE ELSE, even in functions called BY a deferred function, it's a nop.
When called with `nil`, returns `nil`. When called with a non-nil non-error value, wraps it into `Val` which implements the `error` interface.
func Fail ¶ added in v0.1.2
func Fail(fun func(error))
Must be deferred. Runs the function ONLY if there's an ongoing panic, and then re-panics. Idempotently adds a stacktrace.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { logErr := func(err error) { fmt.Println(`caught:`, err) } funcOk := func() { defer try.Fail(logErr) fmt.Println(`not panicking`) } funcFail := func() { defer try.Fail(logErr) fmt.Println(`panicking`) panic(errors.New(`failure`)) } funcOk() _ = try.Catch(funcFail) }
Output: not panicking panicking caught: failure
func Float32 ¶
A "try" function that takes and returns a value of type `float32`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (float32, error) { return 255, nil } fmt.Println(try.Float32(someFunc())) }
Output: 255
func Float32Slice ¶
A "try" function that takes and returns a value of type `[]float32`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]float32, error) { return []float32{255}, nil } fmt.Println(try.Float32Slice(someFunc())) }
Output: [255]
func Float64 ¶
A "try" function that takes and returns a value of type `float64`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (float64, error) { return 255, nil } fmt.Println(try.Float64(someFunc())) }
Output: 255
func Float64Slice ¶
A "try" function that takes and returns a value of type `[]float64`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]float64, error) { return []float64{255}, nil } fmt.Println(try.Float64Slice(someFunc())) }
Output: [255]
func HasStack ¶
True if this error, or any of the errors it wraps, has a stacktrace provided by "github.com/pkg/errors".
func Ignore ¶ added in v0.1.2
func Ignore()
Must be deferred. Catches and ignores ALL panics.
Example ¶
package main import ( "fmt" "os" "github.com/mitranim/try" ) func main() { someFunc := func() { defer try.Ignore() _ = try.ByteSlice(os.ReadFile(`non-existent-file`)) fmt.Println(`file exists`) } someFunc() }
Output:
func IgnoreOnly ¶ added in v0.1.5
Must be deferred. Catches panics; ignores errors that satisfy the provided test; re-panics on other non-nil errors. Idempotently adds a stacktrace.
Example ¶
package main import ( "fmt" "os" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { isErrNoFile := func(err error) bool { return errors.Is(err, os.ErrNotExist) } someFunc := func() { defer try.IgnoreOnly(isErrNoFile) _ = try.ByteSlice(os.ReadFile(`non-existent-file`)) fmt.Println(`file exists`) } someFunc() }
Output:
func Ignoring ¶ added in v0.1.2
func Ignoring(fun func())
Runs a function, catching and ignoring ALL panics.
Example ¶
package main import ( "fmt" "os" "github.com/mitranim/try" ) func main() { maybeRead := func() { _ = try.ByteSlice(os.ReadFile(`non-existent-file`)) fmt.Println(`file exists`) } try.Ignoring(maybeRead) }
Output:
func IgnoringOnly ¶ added in v0.1.5
Runs a function, catching and ignoring only the panics that satisfy the provided test. Idempotently adds a stacktrace to all panics.
Example ¶
package main import ( "fmt" "os" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { isErrNoFile := func(err error) bool { return errors.Is(err, os.ErrNotExist) } maybeRead := func() { _ = try.ByteSlice(os.ReadFile(`non-existent-file`)) fmt.Println(`file exists`) } try.IgnoringOnly(isErrNoFile, maybeRead) }
Output:
func Int ¶
A "try" function that takes and returns a value of type `int`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (int, error) { return 255, nil } fmt.Println(try.Int(someFunc())) }
Output: 255
func Int16 ¶
A "try" function that takes and returns a value of type `int16`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (int16, error) { return 255, nil } fmt.Println(try.Int16(someFunc())) }
Output: 255
func Int16Slice ¶
A "try" function that takes and returns a value of type `[]int16`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]int16, error) { return []int16{255}, nil } fmt.Println(try.Int16Slice(someFunc())) }
Output: [255]
func Int32 ¶
A "try" function that takes and returns a value of type `int32`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (int32, error) { return 255, nil } fmt.Println(try.Int32(someFunc())) }
Output: 255
func Int32Slice ¶
A "try" function that takes and returns a value of type `[]int32`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]int32, error) { return []int32{255}, nil } fmt.Println(try.Int32Slice(someFunc())) }
Output: [255]
func Int64 ¶
A "try" function that takes and returns a value of type `int64`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (int64, error) { return 255, nil } fmt.Println(try.Int64(someFunc())) }
Output: 255
func Int64Slice ¶
A "try" function that takes and returns a value of type `[]int64`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]int64, error) { return []int64{255}, nil } fmt.Println(try.Int64Slice(someFunc())) }
Output: [255]
func Int8 ¶
A "try" function that takes and returns a value of type `int8`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (int8, error) { return -127, nil } fmt.Println(try.Int8(someFunc())) }
Output: -127
func Int8Slice ¶
A "try" function that takes and returns a value of type `[]int8`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]int8, error) { return []int8{-127}, nil } fmt.Println(try.Int8Slice(someFunc())) }
Output: [-127]
func IntSlice ¶
A "try" function that takes and returns a value of type `[]int`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]int, error) { return []int{255}, nil } fmt.Println(try.IntSlice(someFunc())) }
Output: [255]
func Interface ¶
func Interface(val interface{}, err error) interface{}
A "try" function that takes and returns a value of type `interface{} value.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (interface{}, error) { return "val", nil } fmt.Println(try.Interface(someFunc())) }
Output: val
func InterfaceSlice ¶
func InterfaceSlice(val []interface{}, err error) []interface{}
A "try" function that takes and returns a value of type `[]interface{}`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]interface{}, error) { return []interface{}{"val"}, nil } fmt.Println(try.InterfaceSlice(someFunc())) }
Output: [val]
func Ok ¶ added in v0.1.2
func Ok(fun func())
Must be deferred. Runs the function only if there's no panic. Idempotently adds a stacktrace.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { logOk := func() { fmt.Println(`no panic`) } funcOk := func() { defer try.Ok(logOk) fmt.Println(`not panicking`) } funcFail := func() { defer try.Ok(logOk) fmt.Println(`panicking`) panic(errors.New(`failure`)) } funcOk() _ = try.Catch(funcFail) }
Output: not panicking no panic panicking
func Rec ¶
func Rec(ptr *error)
Must be deferred. Recovers from panics, writing the resulting error, if any, to the given pointer. Should be used together with "try"-style functions. Idempotently adds a stacktrace.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { someFunc := func() (err error) { defer try.Rec(&err) try.To(errors.New(`failure A`)) // Will panic, error will be returned. try.To(errors.New(`failure B`)) // Not executed; would panic. try.To(nil) // Not executed; would not panic. return } err := someFunc() fmt.Println(err) }
Output: failure A
func RecChan ¶
func RecChan(errChan chan<- error)
Must be deferred. Version of `Rec` that sends the recovered error, if any, to the given channel. Idempotently adds a stacktrace.
Example ¶
package main import ( "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { someFunc := func(errChan chan error) { defer try.RecChan(errChan) try.To(errors.New(`failure A`)) // Will panic, error will be sent. try.To(errors.New(`failure B`)) // Not executed; would panic. try.To(nil) // Not executed; would not panic. } errs := make(chan error, 256) someFunc(errs) }
Output:
func RecOnly ¶ added in v0.1.2
Must be deferred. Filtered version of `Rec`. Recovers from panics that satisfy the provided test. Re-panics on non-nil errors that don't satisfy the test. Does NOT check errors that are returned normally, without a panic. Should be used together with "try"-style functions. Idempotently adds a stacktrace.
Example ¶
package main import ( "fmt" "os" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { isErrNoFile := func(err error) bool { return errors.Is(err, os.ErrNotExist) } someFunc := func() (err error) { defer try.RecOnly(&err, isErrNoFile) _ = try.ByteSlice(os.ReadFile(`non-existent-file`)) fmt.Println(`file exists`) return } err := someFunc() fmt.Println(err) }
Output: open non-existent-file: no such file or directory
func RecWith ¶
func RecWith(fun func(error))
Must be deferred. Recovery for background goroutines that have nowhere to return their error. Unlike the other "rec" functions, this doesn't send the error anywhere; instead it calls the provided function ONLY if the error was non-nil.
Functions that CAN return errors should use the other "rec" functions instead.
Example ¶
package main import ( "log" "github.com/mitranim/try" ) func main() { bgFun := func() { defer try.RecWith(func(err error) { log.Printf("failed to X: %+v\n", err) }) panic("fail") } go bgFun() }
Output:
func RecWithMessage ¶
Must be deferred. Combination of `Rec` and `WithMessage`. Recovers from panics and adds a message. Idempotently adds a stacktrace.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { someFunc := func() (err error) { defer try.RecWithMessage(&err, `failed to X`) try.To(errors.New(`failure A`)) // Will panic, error will be wrapped and returned. try.To(errors.New(`failure B`)) // Not executed; would panic. try.To(nil) // Not executed; would not panic. return } err := someFunc() fmt.Println(err) }
Output: failed to X: failure A
func RecWithMessagef ¶
Must be deferred. Combination of `Rec` and `WithMessagef`. Recovers from panics and adds a message. Idempotently adds a stacktrace.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { someFunc := func() (err error) { defer try.RecWithMessagef(&err, `failed to %v`, `X`) try.To(errors.New(`failure A`)) // Will panic, error will be wrapped and returned. try.To(errors.New(`failure B`)) // Not executed; would panic. try.To(nil) // Not executed; would not panic. return } err := someFunc() fmt.Println(err) }
Output: failed to X: failure A
func Rune ¶
A "try" function that takes and returns a value of type `rune`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (rune, error) { return 255, nil } fmt.Println(try.Rune(someFunc())) }
Output: 255
func RuneSlice ¶
A "try" function that takes and returns a value of type `[]rune`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]rune, error) { return []rune{255}, nil } fmt.Println(try.RuneSlice(someFunc())) }
Output: [255]
func String ¶
A "try" function that takes and returns a value of type `string`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (string, error) { return "str", nil } fmt.Println(try.String(someFunc())) }
Output: str
func StringSlice ¶
A "try" function that takes and returns a value of type `[]string`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]string, error) { return []string{"val"}, nil } fmt.Println(try.StringSlice(someFunc())) }
Output: [val]
func To ¶
func To(err error)
Simplifies control flow by panicking on non-nil errors. Should be used in conjunction with `Rec`.
If the error doesn't already have a stacktrace, adds one via "github.com/pkg/errors". Stacktraces are essential for such exception-like control flow. Without them, debugging would be incredibly tedious.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { someFunc := func() (err error) { defer try.Rec(&err) try.To(errors.New(`failure A`)) // Will panic, error will be returned. try.To(errors.New(`failure B`)) // Not executed; would panic. try.To(nil) // Not executed; would not panic. return } err := someFunc() fmt.Println(err) }
Output: failure A
func Trace ¶
func Trace()
Must be deferred. Tool for adding a stacktrace to an arbitrary panic. Unlike the "rec" functions, this does NOT prevent the panic from propagating. It simply ensures that there's a stacktrace, then re-panics.
Caution: due to idiosyncrasies of `recover()`, this works ONLY when deferred directly. Anything other than `defer try.Trace()` will NOT work.
Example ¶
package main import ( "github.com/mitranim/try" ) func main() { defer try.Trace() if false { panic("unreachable") } }
Output:
func Trans ¶ added in v0.1.2
Must be deferred. Short for "transmute" or "transform". Catches an ongoing panic, transforms the error by calling the provided function, and then re-panics via `To`. Can be used to ignore specific errors, by converting them to nil, which prevents the second panic. Idempotently adds a stacktrace.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { type ErrPub struct{ error } toErrPub := func(err error) error { if err != nil { return ErrPub{err} } return nil } someFunc := func() { defer try.Trans(toErrPub) panic(errors.New(`failure`)) } err := try.Catch(someFunc) fmt.Println(errors.As(err, new(ErrPub))) }
Output: true
func Transing ¶ added in v0.1.5
Runs a function, "transmuting" the resulting panics by calling the provided transformer, which may choose to suppress or wrap specific error types. See `Trans`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { type ErrPub struct{ error } toErrPub := func(err error) error { if err != nil { return ErrPub{err} } return nil } someFunc := func() { panic(errors.New(`failure`)) } err := try.Catch(func() { try.Transing(toErrPub, someFunc) }) fmt.Println(errors.As(err, new(ErrPub))) }
Output: true
func Uint ¶
A "try" function that takes and returns a value of type `uint`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (uint, error) { return 255, nil } fmt.Println(try.Uint(someFunc())) }
Output: 255
func Uint16 ¶
A "try" function that takes and returns a value of type `uint16`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (uint16, error) { return 255, nil } fmt.Println(try.Uint16(someFunc())) }
Output: 255
func Uint16Slice ¶
A "try" function that takes and returns a value of type `[]uint16`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]uint16, error) { return []uint16{255}, nil } fmt.Println(try.Uint16Slice(someFunc())) }
Output: [255]
func Uint32 ¶
A "try" function that takes and returns a value of type `uint32`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (uint32, error) { return 255, nil } fmt.Println(try.Uint32(someFunc())) }
Output: 255
func Uint32Slice ¶
A "try" function that takes and returns a value of type `[]uint32`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]uint32, error) { return []uint32{255}, nil } fmt.Println(try.Uint32Slice(someFunc())) }
Output: [255]
func Uint64 ¶
A "try" function that takes and returns a value of type `uint64`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (uint64, error) { return 255, nil } fmt.Println(try.Uint64(someFunc())) }
Output: 255
func Uint64Slice ¶
A "try" function that takes and returns a value of type `[]uint64`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]uint64, error) { return []uint64{255}, nil } fmt.Println(try.Uint64Slice(someFunc())) }
Output: [255]
func Uint8 ¶
A "try" function that takes and returns a value of type `uint8`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (uint8, error) { return 255, nil } fmt.Println(try.Uint8(someFunc())) }
Output: 255
func Uint8Slice ¶
A "try" function that takes and returns a value of type `[]uint8`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]uint8, error) { return []uint8{255}, nil } fmt.Println(try.Uint8Slice(someFunc())) }
Output: [255]
func UintSlice ¶
A "try" function that takes and returns a value of type `[]uint`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]uint, error) { return []uint{255}, nil } fmt.Println(try.UintSlice(someFunc())) }
Output: [255]
func Uintptr ¶
A "try" function that takes and returns a value of type `uintptr`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() (uintptr, error) { return 255, nil } fmt.Println(try.Uintptr(someFunc())) }
Output: 255
func UintptrSlice ¶
A "try" function that takes and returns a value of type `[]uintptr`.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" ) func main() { someFunc := func() ([]uintptr, error) { return []uintptr{255}, nil } fmt.Println(try.UintptrSlice(someFunc())) }
Output: [255]
func WithMessage ¶
Must be deferred. Wraps a non-nil error, prepending the message. Unlike `RecWithMessage`, does NOT implicitly recover or add a stacktrace.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { someFunc := func() (err error) { defer try.WithMessage(&err, `failed to X`) return errors.New(`failure A`) // Will be wrapped. return errors.New(`failure B`) // Not executed; would panic. return nil // Not executed; would not panic. } err := someFunc() fmt.Println(err) }
Output: failed to X: failure A
func WithMessagef ¶
Must be deferred. Wraps a non-nil error, prepending the message. Unlike `RecWithMessagef`, does NOT implicitly recover or add a stacktrace.
Example ¶
package main import ( "fmt" "github.com/mitranim/try" "github.com/pkg/errors" ) func main() { someFunc := func() (err error) { defer try.WithMessagef(&err, `failed to %v`, `X`) return errors.New(`failure A`) // Will panic, error will be wrapped. return errors.New(`failure B`) // Not executed; would panic. return nil // Not executed; would not panic. } err := someFunc() fmt.Println(err) }
Output: failed to X: failure A
func WithStack ¶
Adds a stacktrace via "github.com/pkg/errors", unless the error already has one. This exists because `errors.WithStack` ALWAYS wraps an error and adds a stacktrace, even when it would be redundant.
Should be used when it's unknown whether the error has a stacktrace. When the error is known to NOT have a stacktrace, use `errors.WithStack`, because this function adds its own frame, and `errors.WithStack` does not.
When called with `nil`, returns `nil`.