MCPcopy Index your code
hub / github.com/cockroachdb/errors / formatErrorInternal

Function formatErrorInternal

errbase/format_error.go:87–186  ·  view source on GitHub ↗

formatErrorInternal is the shared logic between FormatError and FormatErrorRedactable. When the redactableOutput argument is true, the fmt.State argument is really a redact.SafePrinter and casted down as necessary. If verb and flags are not one of the supported error formatting combinations (in pa

(err error, s fmt.State, verb rune, redactableOutput bool)

Source from the content-addressed store, hash-verified

85// argument is ignored. This limitation may be lifted in a later
86// version.
87func formatErrorInternal(err error, s fmt.State, verb rune, redactableOutput bool) {
88 // Assuming this function is only called from the Format method, and given
89 // that FormatError takes precedence over Format, it cannot be called from
90 // any package that supports errors.Formatter. It is therefore safe to
91 // disregard that State may be a specific printer implementation and use one
92 // of our choice instead.
93
94 p := state{State: s, redactableOutput: redactableOutput}
95
96 switch {
97 case verb == 'v' && s.Flag('+') && !s.Flag('#'):
98 // Here we are going to format as per %+v, into p.buf.
99 //
100 // We need to start with the innermost (root cause) error first,
101 // then the layers of wrapping from innermost to outermost, so as
102 // to enable stack trace de-duplication. This requires a
103 // post-order traversal. Since we have a linked list, the best we
104 // can do is a recursion.
105 p.formatRecursive(
106 err,
107 true, /* isOutermost */
108 true, /* withDetail */
109 false, /* withDepth */
110 0, /* depth */
111 )
112
113 // We now have all the data, we can render the result.
114 p.formatEntries(err)
115
116 // We're done formatting. Apply width/precision parameters.
117 p.finishDisplay(verb)
118
119 case !redactableOutput && verb == 'v' && s.Flag('#'):
120 // We only know how to process %#v if redactable output is not
121 // requested. This is because the structured output may emit
122 // arbitrary unsafe strings without redaction markers,
123 // or improperly balanced/escaped redaction markers.
124 if stringer, ok := err.(fmt.GoStringer); ok {
125 io.WriteString(&p.finalBuf, stringer.GoString())
126 } else {
127 // Not a GoStringer: delegate to the pretty library.
128 fmt.Fprintf(&p.finalBuf, "%# v", pretty.Formatter(err))
129 }
130 p.finishDisplay(verb)
131
132 case verb == 's' ||
133 // We only handle %v/%+v or other combinations here; %#v is unsupported.
134 (verb == 'v' && !s.Flag('#')) ||
135 // If redactable output is not requested, then we also
136 // know how to format %x/%X (print bytes of error message in hex)
137 // and %q (quote the result).
138 // If redactable output is requested, then we don't know
139 // how to perform these exotic verbs, because they
140 // may muck with the redaction markers. In this case,
141 // we simply refuse the format as per the default clause below.
142 (!redactableOutput && (verb == 'x' || verb == 'X' || verb == 'q')):
143 // Only the error message.
144 //

Callers 2

FormatErrorFunction · 0.85
FormatRedactableErrorFunction · 0.85

Calls 5

formatRecursiveMethod · 0.95
formatEntriesMethod · 0.95
finishDisplayMethod · 0.95
StringMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…