-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patherror_parse.go
96 lines (86 loc) · 2.6 KB
/
error_parse.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
package dic
import (
"errors"
"reflect"
"strings"
)
// Unbind Разыменовывает error, представленный стандартным интерфейсом ошибки, в объект IError.
// Если в error не содержится объекта удовлетворяющего интерфейсу IError, возвращается nil.
func (errs *Errors) Unbind(err error) (ierr IError) {
var (
bind *tError
ok bool
)
if ok = errors.As(err, &bind); ok {
ierr = bind
}
return
}
// ParseError Анализ ошибки завёрнутой в стандартный интерфейс ошибки и извлечение IError.
// Если ошибка IError не найдена, создание новой ошибки с интерфейсом IError на базе ошибки error.
func (errs *Errors) ParseError(e error, db ...any) (ret IError) {
var (
bind *tError
rv reflect.Value
n, d int
)
// Список поиска.
db = append([]any{errs}, db...)
// Неизвестная ошибка.
if e == nil {
return singletonErrors.Unknown
}
if ret = errs.Unbind(e); ret != nil {
return
}
// Поиск ошибки в справочниках.
for d = 0; d < len(db) && bind == nil; d++ {
rv = reflect.ValueOf(db[d])
if rv.Kind() == reflect.Pointer {
rv = rv.Elem()
}
for n = 0; n < rv.NumField(); n++ {
if rv.Field(n).Kind() == reflect.Struct {
continue
}
if !rv.Field(n).CanInterface() {
continue
}
errors.As(rv.Field(n).Interface().(*tError), &bind)
if errors.Is(bind.anchor, e) || strings.EqualFold(bind.anchor.Error(), e.Error()) {
break
}
bind = nil
}
}
if bind != nil {
ret = bind
return
}
// Попытка извлечения корневой вложенной ошибки.
bind = &tError{anchor: errors.Unwrap(e)}
if bind.anchor == nil {
bind.anchor = e
}
// Создание новой ошибки на базе error.
ret = &tError{
template: e.Error(),
templateArgs: []string{},
anchor: bind.anchor,
args: []any{},
}
return
}
// NewError Создание объекта под интерфейс IError,
// функция предназначена для формирования настраиваемых справочников.
func (errs *Errors) NewError(template string, arg ...string) IError {
var erro *tError
template = strings.TrimSpace(template)
erro = &tError{
template: template,
templateArgs: make([]string, 0, len(arg)),
anchor: errors.New(template),
}
erro.templateArgs = append(erro.templateArgs, arg...)
return erro
}