-
Notifications
You must be signed in to change notification settings - Fork 0
/
handler.go
105 lines (93 loc) · 2.4 KB
/
handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package catch
import (
"fmt"
"reflect"
)
var (
ERR_DESTINATION_UNADDRESSABLE_VALUE = "destination using unaddressable value, %s must be a pointer or nil"
ERR_NOT_ASSIGNABLE_TO_SPECIFIC_TYPE = "value of type %v is not assignable to type %v"
ERR_INVALID_MEMORY_ADDRESS = "invalid memory address or nil pointer"
)
type handler struct {
err error
dst interface{}
result interface{}
}
type HandlerInterface interface {
Assign(result interface{}) (err error)
}
type OnPanicHandler struct {
handler
callback func(err interface{})
}
type OnFailureHandler struct {
handler
callback func(err interface{}) (dst interface{})
}
// OnSuccessHandler success action
type OnSuccessHandler struct {
handler
callback func() (dst interface{})
}
type FinallyHandler struct {
handler
callback func() (dst interface{})
}
var defaultSuccessFunctionHandling = OnSuccessHandler{
callback: func() (dst interface{}) {
return
},
}
var defaultFailureFunctionHandling = OnFailureHandler{
callback: func(err interface{}) (dst interface{}) {
return
},
}
var defaultFinally = FinallyHandler{
callback: func() (dst interface{}) {
return
},
}
// SetError used for assigning error
func (h *handler) SetError(err error) {
h.err = err
}
// Currently, because the several handler has same function action for `Assign`, so we define `Assign` to parent
func (h *handler) Assign(result interface{}) (err error) {
h.result = result
if h.dst == nil {
return
}
if reflect.ValueOf(h.dst).Kind() != reflect.Ptr {
err = fmt.Errorf(ERR_DESTINATION_UNADDRESSABLE_VALUE, "`dst`")
return
}
destinationType := reflect.TypeOf(h.dst)
resultType := reflect.TypeOf(h.result)
if resultType == nil {
dstElem := reflect.ValueOf(h.dst).Elem()
dstElem.Set(reflect.Zero(dstElem.Type()))
return
}
if !resultType.AssignableTo(destinationType) {
err = fmt.Errorf(ERR_NOT_ASSIGNABLE_TO_SPECIFIC_TYPE, resultType, destinationType)
// give compatibility although `result` is pointer or not
destinationElem := destinationType.Elem()
if destinationElem != resultType {
return
}
err = nil
}
// give compatibility although `result` is pointer or not
setValue := reflect.ValueOf(h.result)
dstValue := reflect.ValueOf(h.dst)
if setValue.Kind() == reflect.Ptr {
setValue = setValue.Elem()
}
dstValue.Elem().Set(setValue)
return
}
// Override parent function
func (p *OnPanicHandler) Assign(result interface{}) (err error) {
return
}