Skip to content

Commit e9bb049

Browse files
authored
Fix/conn check (#38)
1 parent 0373883 commit e9bb049

22 files changed

Lines changed: 1111 additions & 79 deletions

File tree

errors/err_wrap.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,14 @@ func (e *ErrWrap) String() string {
4949
func (e *ErrWrap) MarshalJSON() ([]byte, error) {
5050
data := errJsonify(e.err)
5151
data["kind"] = e.Kind()
52-
data["fields"] = e.pb.Tags
53-
data["stacks"] = e.pb.Stacks
52+
if len(e.pb.Tags) > 0 {
53+
data["fields"] = e.pb.Tags
54+
}
55+
56+
if len(e.pb.Stacks) > 0 {
57+
data["stacks"] = e.pb.Stacks
58+
}
59+
5460
data["caller"] = e.pb.Caller
5561
return jjson.Marshal(data)
5662
}

errors/errcheck/check.go

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
package errcheck
2+
3+
import (
4+
"context"
5+
"runtime/debug"
6+
7+
"github.com/pubgo/funk/errors"
8+
"github.com/pubgo/funk/log"
9+
"github.com/samber/lo"
10+
)
11+
12+
func RecoveryAndCheck(setter *error, callbacks ...func(err error) error) {
13+
if setter == nil {
14+
debug.PrintStack()
15+
panic("setter is nil")
16+
}
17+
18+
err := errors.Parse(recover())
19+
gErr := *setter
20+
if err == nil && gErr == nil {
21+
return
22+
}
23+
24+
if err == nil {
25+
err = gErr
26+
}
27+
28+
for _, fn := range callbacks {
29+
err = fn(err)
30+
if err == nil {
31+
return
32+
}
33+
}
34+
35+
*setter = errors.WrapCaller(err, 1)
36+
}
37+
38+
func Check(errSetter *error, err error, contexts ...context.Context) bool {
39+
if errSetter == nil {
40+
debug.PrintStack()
41+
panic("errSetter is nil")
42+
}
43+
44+
if err == nil {
45+
return false
46+
}
47+
48+
if (*errSetter) != nil {
49+
log.Err(*errSetter).Msgf("errcheck: setter is not nil, err=%v", *errSetter)
50+
return true
51+
}
52+
53+
var ctx = lo.FirstOr(contexts, context.Background())
54+
for _, fn := range GetCheckersFromCtx(ctx) {
55+
err = fn(ctx, err)
56+
if err == nil {
57+
return false
58+
}
59+
}
60+
61+
*errSetter = errors.WrapCaller(err, 1)
62+
return true
63+
}
64+
65+
func CheckCtx(ctx context.Context, errSetter *error, err error, errCheckers ...ErrChecker) bool {
66+
if errSetter == nil {
67+
debug.PrintStack()
68+
panic("errSetter is nil")
69+
}
70+
71+
if err == nil {
72+
return false
73+
}
74+
75+
// err No checking, repeat setting
76+
if (*errSetter) != nil {
77+
log.Err(*errSetter, ctx).Msgf("setter is not nil, err=%v", *errSetter)
78+
return true
79+
}
80+
81+
for _, fn := range append(GetCheckersFromCtx(ctx), errCheckers...) {
82+
err = fn(ctx, err)
83+
if err == nil {
84+
return false
85+
}
86+
}
87+
88+
*errSetter = errors.WrapCaller(err, 1)
89+
return true
90+
}
91+
92+
func NewChecker(ctx context.Context, errSetter *error, errCheckers ...ErrChecker) *Checker {
93+
if errSetter == nil {
94+
debug.PrintStack()
95+
panic("errSetter is nil")
96+
}
97+
98+
if ctx == nil {
99+
ctx = context.Background()
100+
}
101+
102+
return &Checker{ctx: ctx, errSetter: errSetter, errCheckers: errCheckers}
103+
}
104+
105+
type Checker struct {
106+
ctx context.Context
107+
errSetter *error
108+
errCheckers []ErrChecker
109+
}
110+
111+
func (c *Checker) Check(err error, errCheckers ...ErrChecker) bool {
112+
if err == nil {
113+
return false
114+
}
115+
116+
// err No checking, repeat setting
117+
if (*c.errSetter) != nil {
118+
log.Err(*c.errSetter, c.ctx).Msgf("setter is not nil, err=%v", *c.errSetter)
119+
return true
120+
}
121+
122+
checkers := append(append(GetCheckersFromCtx(c.ctx), c.errCheckers...), errCheckers...)
123+
for _, fn := range checkers {
124+
err = fn(c.ctx, err)
125+
if err == nil {
126+
return false
127+
}
128+
}
129+
130+
*c.errSetter = errors.WrapCaller(err, 1)
131+
return true
132+
}
133+
134+
func (c *Checker) Recovery() {
135+
err := errors.Parse(recover())
136+
gErr := *c.errSetter
137+
if err == nil && gErr == nil {
138+
return
139+
}
140+
141+
if err == nil {
142+
err = gErr
143+
}
144+
145+
checkers := append(GetCheckersFromCtx(c.ctx), c.errCheckers...)
146+
for _, fn := range checkers {
147+
err = fn(c.ctx, err)
148+
if err == nil {
149+
return
150+
}
151+
}
152+
153+
*c.errSetter = errors.WrapCaller(err, 1)
154+
}

errors/errcheck/context.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package errcheck
2+
3+
import (
4+
"context"
5+
)
6+
7+
type checkCtx struct{}
8+
9+
type ErrChecker func(context.Context, error) error
10+
11+
func CreateCtx(ctx context.Context, errChecks []ErrChecker) context.Context {
12+
if ctx == nil {
13+
ctx = context.Background()
14+
}
15+
return context.WithValue(ctx, checkCtx{}, errChecks)
16+
}
17+
18+
func GetCheckersFromCtx(ctx context.Context) []ErrChecker {
19+
if ctx == nil {
20+
return nil
21+
}
22+
23+
checkers, ok := ctx.Value(checkCtx{}).([]ErrChecker)
24+
if !ok {
25+
return nil
26+
}
27+
28+
return checkers
29+
}

errors/errors.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
)
1414

1515
func IfErr(err error, fn func(err error) error) error {
16-
if generic.IsNil(err) {
16+
if err == nil {
1717
return nil
1818
}
1919

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package aherrcheck
2+
3+
import (
4+
"context"
5+
"reflect"
6+
7+
"github.com/pubgo/funk/stack"
8+
)
9+
10+
var errChecks []func(context.Context, error) error
11+
12+
func RegisterErrCheck(f func(context.Context, error) error) {
13+
var checkFrame = stack.CallerWithFunc(f)
14+
for _, errFunc := range errChecks {
15+
if reflect.DeepEqual(checkFrame, stack.CallerWithFunc(errFunc)) {
16+
return
17+
}
18+
}
19+
20+
errChecks = append(errChecks, f)
21+
}
22+
23+
func GetErrChecks() []func(context.Context, error) error { return errChecks }
24+
25+
func GetErrCheckFrames() []*stack.Frame {
26+
var frames []*stack.Frame
27+
for _, err := range errChecks {
28+
frames = append(frames, stack.CallerWithFunc(err))
29+
}
30+
return frames
31+
}
32+
33+
func RemoveErrCheck(f func(context.Context, error) error) {
34+
var checkFrame = stack.CallerWithFunc(f)
35+
var index = -1
36+
for idx, errFunc := range errChecks {
37+
if reflect.DeepEqual(checkFrame, stack.CallerWithFunc(errFunc)) {
38+
index = idx
39+
break
40+
}
41+
}
42+
43+
if index != -1 {
44+
errChecks = append(errChecks[:index], errChecks[index+1:]...)
45+
}
46+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package aherrcheck
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func errCheck1(ctx context.Context, err error) error {
11+
return err
12+
}
13+
14+
func TestErrCheck(t *testing.T) {
15+
assert.Equal(t, len(GetErrCheckFrames()), 0)
16+
17+
RegisterErrCheck(errCheck1)
18+
assert.Equal(t, len(GetErrCheckFrames()), 1)
19+
20+
RegisterErrCheck(errCheck1)
21+
assert.Equal(t, len(GetErrCheckFrames()), 1)
22+
23+
RemoveErrCheck(errCheck1)
24+
assert.Equal(t, len(GetErrCheckFrames()), 0)
25+
}

0 commit comments

Comments
 (0)