Commit 936e54ee authored by Kirill Smelkov's avatar Kirill Smelkov

exc: Turn it into real package

Export functions that client would use and adjust their names taking
into account that now there is a package prefix. So e.g.

	raise		-> exc.Raise
	errcatch	-> exc.Catch
	erronunwind	-> exc.Onunwind
	...
parent 383fe35f
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
// //
// See COPYING file for full licensing terms. // See COPYING file for full licensing terms.
// Git-backup | Exception-style errors // Package exc provides exception-style error handling for Go
package main package exc
import ( import (
"fmt" "fmt"
...@@ -21,10 +21,10 @@ import ( ...@@ -21,10 +21,10 @@ import (
"lab.nexedi.com/kirr/go123/xruntime" "lab.nexedi.com/kirr/go123/xruntime"
) )
// error type which is raised by raise(arg) // error type which is raised by Raise(arg)
type Error struct { type Error struct {
arg interface{} arg interface{}
link *Error // chain of linked Error(s) - see e.g. errcontext() link *Error // chain of linked Error(s) - see e.g. Context()
} }
func (e *Error) Error() string { func (e *Error) Error() string {
...@@ -49,7 +49,7 @@ func (e *Error) Error() string { ...@@ -49,7 +49,7 @@ func (e *Error) Error() string {
// turn any value into Error // turn any value into Error
// if v is already Error - it stays the same // if v is already Error - it stays the same
// otherwise new Error is created // otherwise new Error is created
func aserror(v interface{}) *Error { func Aserror(v interface{}) *Error {
if e, ok := v.(*Error); ok { if e, ok := v.(*Error); ok {
return e return e
} }
...@@ -57,13 +57,13 @@ func aserror(v interface{}) *Error { ...@@ -57,13 +57,13 @@ func aserror(v interface{}) *Error {
} }
// raise error to upper level // raise error to upper level
func raise(arg interface{}) { func Raise(arg interface{}) {
panic(aserror(arg)) panic(Aserror(arg))
} }
// raise formatted string // raise formatted string
func raisef(format string, a ...interface{}) { func Raisef(format string, a ...interface{}) {
panic(aserror(fmt.Sprintf(format, a...))) panic(Aserror(fmt.Sprintf(format, a...)))
} }
// raise if err != nil // raise if err != nil
...@@ -71,10 +71,10 @@ func raisef(format string, a ...interface{}) { ...@@ -71,10 +71,10 @@ func raisef(format string, a ...interface{}) {
// var obj *T; // var obj *T;
// err = obj // err = obj
// err != nil is true // err != nil is true
func raiseif(err error) { func Raiseif(err error) {
//if err != nil && !reflect.ValueOf(err).IsNil() { //if err != nil && !reflect.ValueOf(err).IsNil() {
if err != nil { if err != nil {
panic(aserror(err)) panic(Aserror(err))
} }
} }
...@@ -91,7 +91,7 @@ func _errcatch(r interface{}) *Error { ...@@ -91,7 +91,7 @@ func _errcatch(r interface{}) *Error {
// catch error and call f(e) if it was caught. // catch error and call f(e) if it was caught.
// must be called under defer // must be called under defer
func errcatch(f func(e *Error)) { func Catch(f func(e *Error)) {
e := _errcatch(recover()) e := _errcatch(recover())
if e == nil { if e == nil {
return return
...@@ -102,10 +102,10 @@ func errcatch(f func(e *Error)) { ...@@ -102,10 +102,10 @@ func errcatch(f func(e *Error)) {
// be notified when error unwinding is being happening. // be notified when error unwinding is being happening.
// hook into unwinding process with f() call. Returned error is reraised. // hook into unwinding process with f() call. Returned error is reraised.
// see also: errcontext() // see also: Context()
// must be called under defer // must be called under defer
func erronunwind(f func(e *Error) *Error) { func Onunwind(f func(e *Error) *Error) {
// cannot do errcatch(...) // cannot do Catch(...)
// as recover() works only in first-level called functions // as recover() works only in first-level called functions
e := _errcatch(recover()) e := _errcatch(recover())
if e == nil { if e == nil {
...@@ -120,37 +120,37 @@ func erronunwind(f func(e *Error) *Error) { ...@@ -120,37 +120,37 @@ func erronunwind(f func(e *Error) *Error) {
// f is called if error unwinding is happening. // f is called if error unwinding is happening.
// call result is added to raised error as "prefix" context // call result is added to raised error as "prefix" context
// must be called under defer // must be called under defer
func errcontext(f func() interface{}) { func Context(f func() interface{}) {
e := _errcatch(recover()) e := _errcatch(recover())
if e == nil { if e == nil {
return return
} }
arg := f() arg := f()
panic(erraddcontext(e, arg)) panic(Addcontext(e, arg))
} }
// add "prefix" context to error // add "prefix" context to error
func erraddcontext(e *Error, arg interface{}) *Error { func Addcontext(e *Error, arg interface{}) *Error {
return &Error{arg, e} return &Error{arg, e}
} }
var ( var (
_errorpkgname string // package name under which error.go lives _errorpkgname string // package name under which error.go lives
_errorpkgdot string // errorpkg. _errorpkgdot string // errorpkg.
_errorraise string // errorpkg.raise _errorraise string // errorpkg.Raise
) )
func init() { func init() {
_errorpkgname = myname.Pkg() _errorpkgname = myname.Pkg()
_errorpkgdot = _errorpkgname + "." _errorpkgdot = _errorpkgname + "."
_errorraise = _errorpkgname + ".raise" _errorraise = _errorpkgname + ".Raise"
} }
// add calling context to error. // add calling context to error.
// Add calling function names as error context up-to topfunc not including. // Add calling function names as error context up-to topfunc not including.
// see also: erraddcontext() // see also: Addcontext()
func erraddcallingcontext(topfunc string, e *Error) *Error { func Addcallingcontext(topfunc string, e *Error) *Error {
seenraise := false seenraise := false
for _, f := range xruntime.Traceback(2) { for _, f := range xruntime.Traceback(2) {
// do not show anything after raise*() // do not show anything after raise*()
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
// //
// See COPYING file for full licensing terms. // See COPYING file for full licensing terms.
package main package exc
import ( import (
"errors" "errors"
...@@ -20,11 +20,11 @@ import ( ...@@ -20,11 +20,11 @@ import (
) )
func do_raise1() { func do_raise1() {
raise(1) Raise(1)
} }
func TestErrRaiseCatch(t *testing.T) { func TestErrRaiseCatch(t *testing.T) {
defer errcatch(func(e *Error) { defer Catch(func(e *Error) {
if !(e.arg == 1 && e.link == nil) { if !(e.arg == 1 && e.link == nil) {
t.Fatalf("error caught but unexpected: %#v ; want {1, nil}", e) t.Fatalf("error caught but unexpected: %#v ; want {1, nil}", e)
} }
...@@ -50,21 +50,21 @@ func verifyErrChain(t *testing.T, e *Error, argv ...interface{}) { ...@@ -50,21 +50,21 @@ func verifyErrChain(t *testing.T, e *Error, argv ...interface{}) {
} }
func do_onunwind1(t *testing.T) { func do_onunwind1(t *testing.T) {
defer erronunwind(func(e *Error) *Error { defer Onunwind(func(e *Error) *Error {
t.Fatal("on unwind called without raise") t.Fatal("on unwind called without raise")
return nil return nil
}) })
} }
func do_onunwind2() { func do_onunwind2() {
defer erronunwind(func(e *Error) *Error { defer Onunwind(func(e *Error) *Error {
return &Error{2, e} return &Error{2, e}
}) })
do_raise1() do_raise1()
} }
func TestErrOnUnwind(t *testing.T) { func TestErrOnUnwind(t *testing.T) {
defer errcatch(func(e *Error) { defer Catch(func(e *Error) {
verifyErrChain(t, e, 2, 1) verifyErrChain(t, e, 2, 1)
}) })
do_onunwind1(t) do_onunwind1(t)
...@@ -73,21 +73,21 @@ func TestErrOnUnwind(t *testing.T) { ...@@ -73,21 +73,21 @@ func TestErrOnUnwind(t *testing.T) {
} }
func do_context1(t *testing.T) { func do_context1(t *testing.T) {
defer errcontext(func() interface{} { defer Context(func() interface{} {
t.Fatal("on context called without raise") t.Fatal("on context called without raise")
return nil return nil
}) })
} }
func do_context2() { func do_context2() {
defer errcontext(func() interface{} { defer Context(func() interface{} {
return 3 return 3
}) })
do_raise1() do_raise1()
} }
func TestErrContext(t *testing.T) { func TestErrContext(t *testing.T) {
defer errcatch(func(e *Error) { defer Catch(func(e *Error) {
verifyErrChain(t, e, 3, 1) verifyErrChain(t, e, 3, 1)
}) })
do_context1(t) do_context1(t)
...@@ -100,7 +100,7 @@ func do_raise11() { ...@@ -100,7 +100,7 @@ func do_raise11() {
} }
func do_raise3if() { func do_raise3if() {
raiseif(errors.New("3")) Raiseif(errors.New("3"))
} }
func do_raise3if1() { func do_raise3if1() {
...@@ -108,7 +108,7 @@ func do_raise3if1() { ...@@ -108,7 +108,7 @@ func do_raise3if1() {
} }
func do_raise4f() { func do_raise4f() {
raisef("%d", 4) Raisef("%d", 4)
} }
func do_raise4f1() { func do_raise4f1() {
...@@ -126,8 +126,8 @@ func TestErrAddCallingContext(t *testing.T) { ...@@ -126,8 +126,8 @@ func TestErrAddCallingContext(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
func() { func() {
myfunc := myname.Func() myfunc := myname.Func()
defer errcatch(func(e *Error) { defer Catch(func(e *Error) {
e = erraddcallingcontext(myfunc, e) e = Addcallingcontext(myfunc, e)
msg := e.Error() msg := e.Error()
if msg != tt.wanterrcontext { if msg != tt.wanterrcontext {
t.Fatalf("err + calling context: %q ; want %q", msg, tt.wanterrcontext) t.Fatalf("err + calling context: %q ; want %q", msg, tt.wanterrcontext)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment