Skip to content

Commit 221fa0c

Browse files
committed
init
1 parent 5277e55 commit 221fa0c

12 files changed

+761
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.idea

README.assets/graphviz.png

152 KB
Loading

README.md

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# Try-Catch的Go实现
2+
3+
# 一、这是什么?为什么会有这个?
4+
5+
在其他语言中有try-catch的实现,但是在Go里面并没有提供try-catch的实现,但是Go里面很多操作又很容易panic,
6+
7+
当然这不是一个好的最佳实践,只是我们需要让业务能够正常跑起来更健壮以免隔三差五背锅,仅此而已!
8+
9+
# 二、安装
10+
11+
```bash
12+
go get -u github.com/golang-infrastructure/go-try-catch
13+
```
14+
15+
# 三、Try-Catch方法
16+
17+
提供了两种helper方法,一种是比较轻量级的方法,比如当有一段代码需要执行,但是不确定会不会产生错误,就可以这个样子:
18+
19+
```go
20+
package main
21+
22+
import (
23+
"errors"
24+
try_catch "github.com/golang-infrastructure/go-try-catch"
25+
"github.com/stretchr/testify/assert"
26+
"testing"
27+
)
28+
29+
func TestTryCatch(t *testing.T) {
30+
31+
var errFoo = errors.New("foo")
32+
33+
// 正常执行
34+
err := try_catch.TryCatch(func() {
35+
t.Log("ok")
36+
})
37+
assert.Nil(t, err)
38+
39+
// 执行时发生panic
40+
err = try_catch.TryCatch(func() {
41+
panic(errFoo)
42+
})
43+
assert.NotNil(t, err)
44+
assert.ErrorIs(t, err, errFoo)
45+
}
46+
```
47+
48+
如果需要返回值的话:
49+
50+
```go
51+
func TestTryCatchReturn(t *testing.T) {
52+
53+
var errFoo = errors.New("foo")
54+
55+
// 正常执行
56+
v, err := try_catch.TryCatchReturn(func() int {
57+
return 10086
58+
})
59+
assert.Nil(t, err)
60+
assert.Equal(t, 10086, v)
61+
62+
// 执行时发生panic
63+
v, err = try_catch.TryCatchReturn(func() int {
64+
panic(errFoo)
65+
})
66+
assert.NotNil(t, err)
67+
assert.ErrorIs(t, err, errFoo)
68+
}
69+
```
70+
71+
如果需要更多返回值:
72+
73+
```go
74+
func TryCatchReturn2[R1, R2 any](f func() (R1, R2)) (r1 R1, r2 R2, err error)
75+
func TryCatchReturn3[R1, R2, R3 any](f func() (R1, R2, R3)) (r1 R1, r2 R2, r3 R3, err error)
76+
```
77+
78+
79+
80+
# 四、Try-Catch方法链
81+
82+
try-catch方法链就是定义了一些节点表示异常处理流程中的不同阶段,然后每个节点绑定对应的动作向下一阶段转移,整个状态图大概是这个样子的,其中节点是Struct,边是方法:
83+
84+
![graphviz](README.assets/graphviz.png)
85+
86+
Example:
87+
88+
```go
89+
package example
90+
91+
import (
92+
"errors"
93+
"fmt"
94+
try_catch "github.com/golang-infrastructure/go-try-catch"
95+
"testing"
96+
)
97+
98+
func Test(t *testing.T) {
99+
100+
// 正常执行
101+
try_catch.Try(func() {
102+
fmt.Println("ok")
103+
}).Do()
104+
105+
// try发生异常,走catch
106+
var errFoo = errors.New("")
107+
try_catch.Try(func() {
108+
panic(errFoo)
109+
}).Catch(errors.New("bar"), func(err error) {
110+
fmt.Println("bar")
111+
}).Catch(errFoo, func(err error) {
112+
fmt.Println("foo")
113+
}).Do()
114+
115+
// try发生异常,走默认catch
116+
try_catch.Try(func() {
117+
panic(errors.New("test"))
118+
}).Catch(errors.New("bar"), func(err error) {
119+
fmt.Println("bar")
120+
}).Catch(errFoo, func(err error) {
121+
fmt.Println("foo")
122+
}).DefaultCatch(func(err error) {
123+
fmt.Println("other")
124+
}).Do()
125+
126+
// try未发生异常走else
127+
try_catch.Try(func() {
128+
_ = 100 + 19
129+
}).DefaultCatch(func(err error) {
130+
fmt.Println("other")
131+
}).Else(func() {
132+
fmt.Println("else")
133+
}).Do()
134+
135+
// try发生异常,并且走finally
136+
try_catch.Try(func() {
137+
panic(errors.New("test"))
138+
}).DefaultCatch(func(err error) {
139+
fmt.Println("other")
140+
}).Else(func() {
141+
fmt.Println("else")
142+
}).Finally(func() {
143+
fmt.Println("finally")
144+
}).Do()
145+
146+
// try未发生异常,并且走finally
147+
try_catch.Try(func() {
148+
_ = 100 + 19
149+
}).DefaultCatch(func(err error) {
150+
fmt.Println("other")
151+
}).Finally(func() {
152+
fmt.Println("finally")
153+
}).Do()
154+
155+
}
156+
```
157+

example/example_chain_test.go

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package example
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
try_catch "github.com/golang-infrastructure/go-try-catch"
7+
"testing"
8+
)
9+
10+
func Test(t *testing.T) {
11+
12+
// 正常执行
13+
try_catch.Try(func() {
14+
fmt.Println("ok")
15+
}).Do()
16+
17+
// try发生异常,走catch
18+
var errFoo = errors.New("")
19+
try_catch.Try(func() {
20+
panic(errFoo)
21+
}).Catch(errors.New("bar"), func(err error) {
22+
fmt.Println("bar")
23+
}).Catch(errFoo, func(err error) {
24+
fmt.Println("foo")
25+
}).Do()
26+
27+
// try发生异常,走默认catch
28+
try_catch.Try(func() {
29+
panic(errors.New("test"))
30+
}).Catch(errors.New("bar"), func(err error) {
31+
fmt.Println("bar")
32+
}).Catch(errFoo, func(err error) {
33+
fmt.Println("foo")
34+
}).DefaultCatch(func(err error) {
35+
fmt.Println("other")
36+
}).Do()
37+
38+
// try未发生异常走else
39+
try_catch.Try(func() {
40+
_ = 100 + 19
41+
}).DefaultCatch(func(err error) {
42+
fmt.Println("other")
43+
}).Else(func() {
44+
fmt.Println("else")
45+
}).Do()
46+
47+
// try发生异常,并且走finally
48+
try_catch.Try(func() {
49+
panic(errors.New("test"))
50+
}).DefaultCatch(func(err error) {
51+
fmt.Println("other")
52+
}).Else(func() {
53+
fmt.Println("else")
54+
}).Finally(func() {
55+
fmt.Println("finally")
56+
}).Do()
57+
58+
// try未发生异常,并且走finally
59+
try_catch.Try(func() {
60+
_ = 100 + 19
61+
}).DefaultCatch(func(err error) {
62+
fmt.Println("other")
63+
}).Finally(func() {
64+
fmt.Println("finally")
65+
}).Do()
66+
67+
}

example/example_func_test.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package example
2+
3+
import (
4+
"errors"
5+
try_catch "github.com/golang-infrastructure/go-try-catch"
6+
"github.com/stretchr/testify/assert"
7+
"testing"
8+
)
9+
10+
func TestTryCatch(t *testing.T) {
11+
12+
var errFoo = errors.New("foo")
13+
14+
// 正常执行
15+
err := try_catch.TryCatch(func() {
16+
t.Log("ok")
17+
})
18+
assert.Nil(t, err)
19+
20+
// 执行时发生panic
21+
err = try_catch.TryCatch(func() {
22+
panic(errFoo)
23+
})
24+
assert.NotNil(t, err)
25+
assert.ErrorIs(t, err, errFoo)
26+
}
27+
28+
29+
func TestTryCatchReturn(t *testing.T) {
30+
31+
var errFoo = errors.New("foo")
32+
33+
// 正常执行
34+
v, err := try_catch.TryCatchReturn(func() int {
35+
return 10086
36+
})
37+
assert.Nil(t, err)
38+
assert.Equal(t, 10086, v)
39+
40+
// 执行时发生panic
41+
v, err = try_catch.TryCatchReturn(func() int {
42+
panic(errFoo)
43+
})
44+
assert.NotNil(t, err)
45+
assert.ErrorIs(t, err, errFoo)
46+
}

go.mod

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module github.com/golang-infrastructure/go-try-catch
2+
3+
go 1.18
4+
5+
require (
6+
github.com/davecgh/go-spew v1.1.1 // indirect
7+
github.com/pmezard/go-difflib v1.0.0 // indirect
8+
github.com/stretchr/objx v0.5.0 // indirect
9+
github.com/stretchr/testify v1.8.1 // indirect
10+
gopkg.in/yaml.v3 v3.0.1 // indirect
11+
)

go.sum

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
3+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
5+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
6+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
7+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
8+
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
9+
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
10+
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
11+
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
12+
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
13+
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
14+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
15+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
16+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
17+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

state.dot

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
digraph G {
2+
start -> TryHandler[label=Try];
3+
TryHandler -> CatchHandler[label=Catch];
4+
TryHandler -> FinallyHandler[label=Finally];
5+
TryHandler -> DefaultCatchHandler[label=DefaultCatch];
6+
TryHandler -> TryCatchElseHandler[label=Else];
7+
TryHandler -> end[label=Do];
8+
9+
CatchHandler -> CatchHandler[label=Catch];
10+
CatchHandler -> DefaultCatchHandler[label=DefaultCatch];
11+
CatchHandler -> TryCatchElseHandler[label=Else];
12+
CatchHandler -> FinallyHandler[label=Finally];
13+
CatchHandler -> end[label=Do];
14+
15+
DefaultCatchHandler -> TryCatchElseHandler[label=Else];
16+
DefaultCatchHandler -> FinallyHandler[label=Finally];
17+
DefaultCatchHandler -> end[label=Do];
18+
19+
TryCatchElseHandler -> FinallyHandler[label=Finally];
20+
TryCatchElseHandler -> end[label=Do];
21+
22+
FinallyHandler -> end[label=Do];
23+
}

0 commit comments

Comments
 (0)