Ego is an experimental library for exception handling. It models try-catch exception handling using panic and recover.
The panic keyword is used to throw exceptions. ego.Errorf should be used to
create errors with stack traces attached. Exceptions are caught using
ego.Try.
func ThisFunctionThrows() {
panic(ego.Errorf("hello %s", "world"))
}
func ThisFunctionCatches() int {
value, err := ego.Try(func() int {
ThisFunctionThrows()
return 42
})
if err != nil {
// '%+v' prints the error and a stack trace
fmt.Printf("%+v\n", err)
return 0
}
return value
}The ego.Unwrap and ego.AssertNil helpers should be used to convert
traditional Go errors into exceptions.
func UnwrapExample() net.Conn {
return ego.Unwrap(net.Dial("tcp", "golang.org:80"))
}
func AssertNilExample(listener net.Listener) {
ego.AssertNil(listener.Close())
}Exception handling with goroutines is tricky because an uncaught exception in
the goroutine will cause the program to crash. ego.Go should be used to
create goroutines. ego.Go returns an ego.Future that the caller can wait
on. Wait will panic if the goroutine panics, allowing the caller to handle
the exception.
func DoSomethingAsync() {
// Create 2 goroutines that run in parallel
future1 := ego.Go(func() string {
return "hello"
})
future2 := ego.Go(func() string {
return "world"
})
// Wait for the goroutines to finish. Wait will throw an exception if the
// goroutine failed.
fmt.Printf("%s %s", future1.Wait(), future2.Wait())
}Formatting an exception with '%+v' prints a stack trace.
func Print(e ego.Exception) {
fmt.Printf("%+v\n", e)
}Here's an example stack trace.
this is the .Error() message
0: ego.frameA exception_test.go:11
1: ego.frameB exception_test.go:15
2: ego.frameC exception_test.go:19
3: ego.TestFormatException exception_test.go:23