This repository has been archived by the owner on Sep 22, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
error.go
136 lines (115 loc) · 2.97 KB
/
error.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
package apperrors
import (
"errors"
"fmt"
)
// Error is an error that has contextual metadata
type Error struct {
// Err is the original error (you might call it the root cause)
Err error
// Message is an annotated description of the error
Message string
// StatusCode is a status code that is desired to be used for a HTTP response
StatusCode int
// Report represents whether the error should be reported to administrators
Report bool
// StackTrace is a stack trace of the original error
// from the point where it was created
StackTrace StackTrace
}
// New returns an error that formats as the given text.
// It also annotates the error with a stack trace from the point it was called
func New(text string) error {
return &Error{
Err: errors.New(text),
StackTrace: newStackTrace(0),
}
}
// Errorf formats according to a format specifier and returns the string
// as a value that satisfies error.
// It also annotates the error with a stack trace from the point it was called
func Errorf(format string, args ...interface{}) error {
return &Error{
Err: fmt.Errorf(format, args...),
StackTrace: newStackTrace(0),
}
}
// Error implements error interface
func (e *Error) Error() string {
if e.Message != "" {
return e.Message
}
return e.Err.Error()
}
// Copy creates a copy of the current object
func (e *Error) Copy() *Error {
return &Error{
Err: e.Err,
Message: e.Message,
StatusCode: e.StatusCode,
Report: e.Report,
StackTrace: e.StackTrace,
}
}
// Wrap returns an error annotated with a stack trace from the point it was called.
// It returns nil if err is nil
func Wrap(err error) error {
if err == nil {
return nil
}
return wrap(err)
}
func wrap(err error) *Error {
pkgErr := extractPkgError(err)
if appErr, ok := pkgErr.Err.(*Error); ok {
return appErr
}
stackTrace := pkgErr.StackTrace
if stackTrace == nil {
stackTrace = newStackTrace(1)
}
return &Error{
Err: pkgErr.Err,
StackTrace: stackTrace,
Message: pkgErr.Message,
}
}
// Unwrap extracts an underlying *apperrors.Error from an error.
// If the given error isn't eligible for retriving context from,
// it returns nil
func Unwrap(err error) *Error {
if appErr, ok := err.(*Error); ok {
return appErr
}
return nil
}
// WithMessage wraps the error and annotates with the message.
// If err is nil, it returns nil
func WithMessage(err error, msg string) error {
if err == nil {
return nil
}
appErr := wrap(err).Copy()
appErr.Message = msg
return appErr
}
// WithStatusCode wraps the error and annotates with the status code.
// If err is nil, it returns nil
func WithStatusCode(err error, code int) error {
if err == nil {
return nil
}
appErr := wrap(err).Copy()
appErr.StatusCode = code
return appErr
}
// WithReport wraps the error and annotates with the reportability.
// If err is nil, it returns nil
func WithReport(err error) error {
if err == nil {
return nil
}
appErr := wrap(err).Copy()
appErr.Report = true
return appErr
}