--- /dev/null
+package errors
+
+type Error struct {
+ son interface{}
+ reason string
+ action string
+}
+
+func (t Error) Error() string {
+ return t.reason
+}
+
+func Catch(e error, action string) bool {
+ if v, ok := e.(Error); ok {
+ if v.action == action {
+ return true
+ } else if v.son != nil {
+ return Catch((v.son).(Error), action)
+ }
+ }
+ return false
+}
+
+func Grow(e error, son Error) Error {
+ if v, ok := e.(Error); ok {
+ son.son = v
+ } else {
+ son.son = Error{
+ reason: v.Error(),
+ }
+ }
+ return son
+}
+
+func New(reason string, action string) Error {
+ return Error{
+ reason: reason,
+ action: action,
+ }
+}
--- /dev/null
+package errors
+
+import "testing"
+
+func TestXxx(t *testing.T) {
+ var err error
+
+ err = New("r0", "a0")
+
+ if !Catch(err, "a0") {
+ t.Fail()
+ }
+
+ if Catch(err, "a1") {
+ t.Fail()
+ }
+
+ err = Grow(err, New("r1", "a1"))
+
+ if !Catch(err, "a0") {
+ t.Fail()
+ }
+
+ if !Catch(err, "a1") {
+ t.Fail()
+ }
+}