-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathinherit.go
149 lines (124 loc) · 3.22 KB
/
inherit.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package eerror
import (
"fmt"
"reflect"
"runtime/debug"
)
const E_EXTERNALERROR = "E_EXTERNALERROR"
var errorParsedAttributes = []interface{}{
"_eerror_parsed", true,
}
/*
From takes any parameter to convert it as an enhanced error.
Returns the given parameter if it's already an enhanced error instance, or nil
*/
func From(e interface{}) Eerror {
if eerr, ok := e.(Eerror); ok {
return eerr
}
if eerr, ok := e.(*Eerror); ok {
return *eerr
}
if ptr, ok := e.(*interface{}); ok {
return fromError(ptr)
}
return fromError(&e)
}
/*
Is tests relationship between an argument and an enhanced error instance, for error handling.
Useful to test if an enhanced error instance was formed from the given instance parameter
const E_MY_ERROR_ID = "E_MY_ERROR_ID"
var standardError = eerror.NewError(E_MY_ERROR_ID, "Some error")
func errorFunction(myParameter interface{}) eerror.Eerror {
err := standardError.Copy()
err.WithAttribute("parameter", myParameter)
return err
}
func main() {
if eerr := errorFunction("hello world"); !eerr.Is(standardError) {
panic(eerr)
}
}
*/
func (e *Eerror) Is(instance interface{}, log ...interface{}) bool {
var initial = e.getInitialError()
var instanceInitial interface{} = instance
if instanceEerr, ok := instance.(*Eerror); ok {
instanceInitial = instanceEerr.getInitialError()
} else if instanceEerr, ok := instance.(Eerror); ok {
instanceInitial = instanceEerr.getInitialError()
}
if len(log) > 0 {
fmt.Printf("%s %p %p\n", e, initial, e.parent)
fmt.Printf("%s %p %p %s\n", instance, instance, instanceInitial, instanceInitial)
fmt.Println(reflect.TypeOf(initial))
fmt.Println(reflect.TypeOf(instanceInitial))
}
testInstanceID := func(toEerr Eerror) bool {
if withEerr, ok := initial.(Eerror); ok {
if toEerr._instance == withEerr._instance {
return true
}
}
if toEerr._instance == e._instance {
return true
}
return false
}
if toEerr, ok := instanceInitial.(Eerror); ok {
if testInstanceID(toEerr) {
return true
}
}
if toEerr, ok := instanceInitial.(*Eerror); ok {
if testInstanceID(*toEerr) {
return true
}
}
return initial == instanceInitial
}
// Dup ensures a copy of a given enhanced error, reinstanciating contexts and attributes
func (e Eerror) Dup() Eerror {
err := Eerror{
e.parent,
e.identifier,
e.message,
make([]string, len(e.contexts)),
make(map[string]interface{}, len(e.attributes)),
e._instance,
}
copy(err.contexts, e.contexts)
for key, value := range e.attributes {
err.attributes[key] = value
}
return err
}
func (e *Eerror) getInitialError() interface{} {
if parent, ok := e.parent.(*Eerror); ok {
return parent.getInitialError()
} else if parent, ok := e.parent.(Eerror); ok {
return parent.getInitialError()
}
if e.parent != nil {
return *(e.parent.(*interface{}))
}
return e
}
func fromError(err *interface{}) Eerror {
if eerr, ok := parse(*err); ok {
return eerr
}
eerr := Eerror{
err,
E_EXTERNALERROR,
fmt.Sprint(*err),
[]string{},
make(map[string]interface{}, len(errorParsedAttributes)/2),
generateUniqueID(),
}
eerr.WithAttribute("stacktrace", string(debug.Stack()))
eerr.WithAttributes(
errorParsedAttributes...,
)
return eerr
}