Skip to content

Commit

Permalink
[try] new package for handle error
Browse files Browse the repository at this point in the history
  • Loading branch information
leaxoy committed Jul 19, 2022
1 parent 5dd23ce commit 9faa1e8
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 0 deletions.
64 changes: 64 additions & 0 deletions result/try/try.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package try

import (
"runtime"
"strconv"
)

// Error represents an error that occurred during a Try operation.
type Error struct {
cause error
frame runtime.Frame
}

func (e *Error) Error() string {
return e.frame.File + ":" + strconv.Itoa(e.frame.Line) + ": " + e.cause.Error()
}

// Frame returns the frame of the caller of the function that called Try.
func (e *Error) Frame() runtime.Frame { return e.frame }

func (e *Error) Unwrap() error { return e.cause }

func raise(e error) {
pcs := [1]uintptr{}
runtime.Callers(3, pcs[:])
frame, _ := runtime.CallersFrames(pcs[:]).Next()
panic(&Error{cause: e, frame: frame})
}

func Try(err error) {
if err != nil {
raise(err)
}
}

func Try1[A any](a A, err error) A {
if err != nil {
raise(err)
}
return a
}

func Catch(errRef *error) {
if err := recover(); err != nil {
switch err := err.(type) {
case *Error:
*errRef = err.cause
case error:
*errRef = err
default:
panic(err)
}
}
}

func CatchFunc(fn func(e *Error)) {
if err := recover(); err != nil {
if e, ok := err.(*Error); ok {
fn(e)
} else {
panic(err)
}
}
}
30 changes: 30 additions & 0 deletions result/try/try_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package try_test

import (
"errors"
"testing"

"github.com/frankban/quicktest"
"github.com/go-board/std/result/try"
)

func TestTry(t *testing.T) {
a := quicktest.New(t)
a.Run("Error", func(c *quicktest.C) {
defer try.CatchFunc(func(e *try.Error) {
c.Assert(e.Unwrap().Error(), quicktest.Equals, "error")
})
try.Try(errors.New("error"))
})
a.Run("NonError", func(*quicktest.C) {
try.Try(nil)
})
}

func TestTryReturn(t *testing.T) {
a := quicktest.New(t)
a.Run("Return", func(c *quicktest.C) {
x := try.Try1(100, nil)
c.Assert(x, quicktest.Equals, 100)
})
}

0 comments on commit 9faa1e8

Please sign in to comment.