This repository has been archived by the owner on Oct 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmessage.go
155 lines (129 loc) · 5.02 KB
/
message.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
package log
import (
"fmt"
)
//region Factories
// UserMessage constructs a Message.
//
// - Code is an error code allowing an administrator to identify the error that happened.
// - UserMessage is the message that can be printed to the user if needed.
// - Explanation is the explanation string to the system administrator. This is an fmt.Sprintf-compatible string
// - Args are the arguments to Explanation to create a formatted message. It is recommended that these arguments also
// be added as labels to allow system administrators to index the error properly.
func UserMessage(Code string, UserMessage string, Explanation string, Args ...interface{}) Message {
return &message{
code: Code,
userMessage: UserMessage,
explanation: fmt.Sprintf(Explanation, Args...),
labels: map[LabelName]LabelValue{},
}
}
// WrapUser creates a Message wrapping an error with a user-facing message.
//
// - Cause is the original error that can be accessed with the Unwrap method.
// - Code is an error code allowing an administrator to identify the error that happened.
// - UserMessage is the message that can be printed to the user if needed.
// - Explanation is the explanation string to the system administrator. This is an fmt.Sprintf-compatible string
// - Args are the arguments to Explanation to create a formatted message. It is recommended that these arguments also
// be added as labels to allow system administrators to index the error properly.
//goland:noinspection GoUnusedExportedFunction
func WrapUser(Cause error, Code string, User string, Explanation string, Args ...interface{}) WrappingMessage {
return &wrappingMessage{
Message: UserMessage(Code, User, Explanation+" (%v)", append(Args, Cause)...),
cause: Cause,
}
}
// NewMessage creates an internal error with only the explanation for the administrator inserted.
//
// - Code is an error code allowing an administrator to identify the error that happened.
// - Explanation is the explanation string to the system administrator. This is an fmt.Sprintf-compatible string
// - Args are the arguments to Explanation to create a formatted message. It is recommended that these arguments also
// be added as labels to allow system administrators to index the error properly.
func NewMessage(Code string, Explanation string, Args ...interface{}) Message {
return UserMessage(
Code,
"Internal Error",
Explanation,
Args...,
)
}
// Wrap creates a wrapped error with a specific Code and Explanation string. The wrapping method will automatically
// append the error message in brackets.
//
// - Cause is the original error that can be accessed with the Unwrap method.
// - Code is an error code allowing an administrator to identify the error that happened.
// - Explanation is the explanation string to the system administrator. This is an fmt.Sprintf-compatible string
// - Args are the arguments to Explanation to create a formatted message. It is recommended that these arguments also
// be added as labels to allow system administrators to index the error properly.
func Wrap(Cause error, Code string, Explanation string, Args ...interface{}) WrappingMessage {
return &wrappingMessage{
Message: NewMessage(Code, Explanation+" (%v)", append(Args, Cause)...),
cause: Cause,
}
}
//endregion
//region Interfaces
// Message is a message structure for error reporting in ContainerSSH. The actual implementations may differ, but we
// provide the UserMessage method to construct a message that conforms to this interface.
type Message interface {
// NewMessage is the Go-compatible error message.
Error() string
// String returns the string representation of this message.
String() string
// Code is a unique code identifying log messages.
Code() string
// UserMessage is a message that is safe to print/send to the end user.
UserMessage() string
// Explanation is the text explanation for the system administrator.
Explanation() string
// Labels are a set of extra labels for the message containing information.
Labels() Labels
// Label adds a label to the message.
Label(name LabelName, value LabelValue) Message
}
// WrappingMessage is a message that wraps a different error.
type WrappingMessage interface {
Message
// Unwrap returns the original error wrapped in this message.
Unwrap() error
}
//endregion
//region Message implementation
type message struct {
code string
userMessage string
explanation string
labels Labels
}
func (m *message) Code() string {
return m.code
}
func (m *message) UserMessage() string {
return m.userMessage
}
func (m *message) Explanation() string {
return m.explanation
}
func (m *message) Labels() Labels {
return m.labels
}
func (m *message) String() string {
return m.userMessage
}
func (m *message) Label(name LabelName, value LabelValue) Message {
m.labels[name] = value
return m
}
func (m *message) Error() string {
return m.explanation
}
//endregion
//region Wrapping message implementation
type wrappingMessage struct {
Message
cause error
}
func (w wrappingMessage) Unwrap() error {
return w.cause
}
//endregion