-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathformat.go
85 lines (72 loc) · 2.05 KB
/
format.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
package eerror
import (
"fmt"
"reflect"
"sort"
"strings"
)
/*
Error formats the error to a human readable string, as described by the error interface.
Eg: `E_SOMEERROR: My error message (context 1; "context 2 with; (special) chars") [some attribute: some value, some other attribute: (int)1]
*/
func (e Eerror) Error() string {
const contextSeparator = "; "
var contextString string
var attributesString string
if len(e.contexts) > 0 {
contextString = " ("
for i, context := range e.contexts {
if i > 0 {
contextString += contextSeparator
}
contextString += escapeString(context, "();")
}
contextString += ")"
}
if len(e.attributes) > 0 {
attributesString = " ["
keys := make([]string, 0)
for key := range e.attributes {
keys = append(keys, key)
}
sort.Strings(keys)
prependSeparator := false
for _, key := range keys {
value := e.attributes[key]
if prependSeparator {
attributesString += ", "
}
prependSeparator = true
var serializedValue = serialize(value)
if reflect.TypeOf(value).Kind() == reflect.String {
serializedValue = escapeString(serializedValue, "[]:,")
}
attributesString += escapeString(key, "[]:,") + ": " + serializedValue
}
attributesString += "]"
}
return fmt.Sprintf("%s: %s%s%s", escapeString(e.identifier, ":"), escapeString(e.message, ":()[]"), contextString, attributesString)
}
// Map formats the error to a protocol-aware object, marshable without data loss
func (e Eerror) Map() map[string]interface{} {
return map[string]interface{}{
"error": e.Error(),
"code": e.identifier,
"message": e.message,
"contexts": e.contexts,
"attributes": e.attributes,
}
}
func escapeString(s string, chars string) string {
if len(s) == 0 || strings.IndexAny(s, chars+"\"") != -1 {
return fmt.Sprintf("\"%s\"", strings.Replace(s, "\"", "\\\"", -1))
}
return s
}
func serialize(value interface{}) string {
var valueType = reflect.TypeOf(value)
if valueType.Kind() == reflect.String {
return value.(string)
}
return fmt.Sprintf("(%s)%v", valueType, value)
}