-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwrap.go
181 lines (163 loc) · 6.51 KB
/
wrap.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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package errs
import (
"fmt"
"log/slog"
)
// Wrap adds context to an existing error by wrapping it with additional messages.
// It accepts an error and variadic arguments to append to the error message chain.
// Returns a new error with the combined messages and original error context.
//
// Parameters:
// - err: The error to wrap. If this is nil, the function returns nil.
// - args: Variadic arguments representing the additional messages to append to the error message chain.
//
// Returns:
// - A new error with the combined messages and original error context.
// If the provided error is nil, the function returns nil.
func Wrap(err error, args ...any) error {
if err == nil {
return nil
}
return wrap(err, args...)
}
// WrapF formats a string message using the provided format and arguments,
// then wraps it around an existing error to add context.
// If the error is nil, it returns nil.
//
// Parameters:
// - err: The error to wrap. If this is nil, the function returns nil.
// - format: A string format to be used with fmt.Sprintf to create the message.
// - args: Variadic arguments representing the values to be formatted into the message.
//
// Returns:
// - A new error with the formatted message and original error context.
// If the provided error is nil, the function returns nil.
func WrapF(err error, format string, args ...any) error {
if err == nil {
return nil
}
// Use fmt.Sprintf to format the message, then wrap the error.
return wrap(err, fmt.Sprintf(format, args...))
}
// wrap adds context to an existing error by wrapping it with additional messages.
// It accepts an error and variadic arguments to append to the error message chain.
// Returns a new error with the combined messages and original error context.
//
// Parameters:
// - err: The error to wrap. If this is nil, the function returns nil.
// - args: Variadic arguments representing the additional messages to append to the error message chain.
//
// Returns:
// - A new error with the combined messages and original error context.
// If the provided error is nil, the function returns nil.
func wrap(err error, args ...any) error {
// Join the provided arguments into a single message string.
message := JoinMsg(separator, args...)
return &errorString{
// Combine the new message with the original error's message.
message: JoinMsg(separator, message, Unwrap(err)),
origErr: err.Error(),
}
}
// Unwrap retrieves the original message from a wrapped error.
//
// The function unwraps the error by checking if it is of type *errorString.
// If the error is wrapped, it returns the original message from the wrapped error.
// If the error is not wrapped, it returns the error message as is.
//
// Parameters:
// - err: The error to unwrap.
//
// Returns:
// - A string representing the original message if the error is wrapped.
// If the error is not wrapped, it returns the error message as is.
// If the provided error is nil, it returns an empty string.
func Unwrap(err error) string {
if err == nil {
return ""
}
u, ok := err.(*errorString)
if !ok {
return err.Error()
}
return u.unwrap()
}
// UnwrapE unwraps a wrapped error and returns the original error message as a new error.
// If the provided error is not wrapped, it returns the error as is.
// If the original message is empty, it returns nil.
//
// Parameters:
// - err: The error to unwrap. This can be nil.
//
// Returns:
// - An error representing the original message if the error is wrapped.
// If the error is not wrapped, it returns the error as is.
// If the original message is empty, it returns nil.
func UnwrapE(err error) error {
if err == nil {
return nil
}
e, ok := err.(*errorString)
if !ok {
return err
}
return New(e.unwrap())
}
// Log asynchronously logs an error with additional context messages and a request object.
// If the error is nil, it does nothing.
//
// The function logs the error using the appropriate logger based on the current logging level and type.
// It constructs a combined message by joining all provided messages with the separator separator.
// The original error message is logged as the "Error Path" field in the log entry.
// The request object is logged as the "request" field in the log entry.
//
// Parameters:
// - err: The error to log. If this is nil, the function returns without doing anything.
// - req: The request object associated with the error. This can be of any type.
// - msgs: Variadic arguments representing additional messages to include in the log entry.
//
// Returns:
// - This function does not return any value.
func Log(err error, req any, msgs ...any) {
if err == nil {
return
}
// Asynchronously handle the error logging to prevent blocking.
go logError(err, req, msgs...)
}
// logError asynchronously logs an error with additional context messages and a request object.
// If the error is nil, it does nothing.
//
// The function logs the error using the appropriate logger based on the current logging level and type.
// It constructs a combined message by joining all provided messages with the separator separator.
// The original error message is logged as the "Error Path" field in the log entry.
// The request object is logged as the "request" field in the log entry.
//
// Parameters:
// - err: The error to log. If this is nil, the function returns without doing anything.
// - req: The request object associated with the error. This can be of any type.
// - msgs: Variadic arguments representing additional messages to include in the log entry.
//
// Returns:
// - This function does not return any value.
func logError(err error, req any, msgs ...any) {
// Join all provided messages to create a unified error message.
message := JoinMsg(separator, msgs...)
errorPath := slog.String("Error Path", Unwrap(err))
// Retrieve the logger based on the current logging level and type.
getLogger(message, errorPath, slog.Any("request", req))
}
// getLogger retrieves and logs an error message with additional context using the appropriate logger.
// It iterates through a list of sloggers and asynchronously logs the error message with the provided arguments.
//
// Parameters:
// - msg: A string representing the error message to be logged.
// - args: Variadic arguments representing additional context to be logged alongside the error message.
//
// Returns:
// - This function does not return any value. It logs the error message asynchronously using the slogLoggers.
func getLogger(msg string, args ...any) {
for _, slog := range slogLoggers {
go slog.Error(msg, args...)
}
}