Skip to content

Commit f2d978b

Browse files
committed
Fix error message printing
1 parent 3239717 commit f2d978b

File tree

1 file changed

+28
-16
lines changed

1 file changed

+28
-16
lines changed

cli/root.go

+28-16
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,7 @@ type prettyErrorFormatter struct {
10161016
// format formats the error to the console. This error should be human
10171017
// readable.
10181018
func (p *prettyErrorFormatter) format(err error) {
1019-
output := cliHumanFormatError(err, &formatOpts{
1019+
output, _ := cliHumanFormatError(err, &formatOpts{
10201020
Verbose: p.verbose,
10211021
})
10221022
// always trail with a newline
@@ -1030,13 +1030,23 @@ type formatOpts struct {
10301030
const indent = " "
10311031

10321032
// cliHumanFormatError formats an error for the CLI. Newlines and styling are
1033-
// included.
1034-
func cliHumanFormatError(err error, opts *formatOpts) string {
1033+
// included. The second return value is true if the error is special and the error
1034+
// chain has custom formatting applied.
1035+
//
1036+
// If you change this code, you can use the cli "example-errors" tool to
1037+
// verify all errors still look ok.
1038+
//
1039+
// go run main.go exp example-error <type>
1040+
// go run main.go exp example-error api
1041+
// go run main.go exp example-error cmd
1042+
// go run main.go exp example-error multi-error
1043+
// go run main.go exp example-error validation
1044+
func cliHumanFormatError(err error, opts *formatOpts) (string, bool) {
10351045
if opts == nil {
10361046
opts = &formatOpts{}
10371047
}
10381048
if err == nil {
1039-
return "<nil>"
1049+
return "<nil>", true
10401050
}
10411051

10421052
if multi, ok := err.(interface{ Unwrap() []error }); ok {
@@ -1045,40 +1055,41 @@ func cliHumanFormatError(err error, opts *formatOpts) string {
10451055
// Format as a single error
10461056
return cliHumanFormatError(multiErrors[0], opts)
10471057
}
1048-
return formatMultiError(multiErrors, opts)
1058+
return formatMultiError(multiErrors, opts), false
10491059
}
10501060

10511061
// First check for sentinel errors that we want to handle specially.
10521062
// Order does matter! We want to check for the most specific errors first.
10531063
//var sdkError *codersdk.Error
10541064
//if errors.As(err, &sdkError) {
10551065
if sdkError, ok := err.(*codersdk.Error); ok {
1056-
return formatCoderSDKError(sdkError, opts)
1066+
return formatCoderSDKError(sdkError, opts), false
10571067
}
10581068

10591069
//var cmdErr *clibase.RunCommandError
10601070
//if errors.As(err, &cmdErr) {
10611071
if cmdErr, ok := err.(*clibase.RunCommandError); ok {
1062-
return formatRunCommandError(cmdErr, opts)
1072+
return formatRunCommandError(cmdErr, opts), false
10631073
}
10641074

10651075
uw, ok := err.(interface{ Unwrap() error })
10661076
if ok {
1067-
msg := cliHumanFormatError(uw.Unwrap(), opts)
1068-
if msg != "" {
1069-
return msg
1077+
msg, special := cliHumanFormatError(uw.Unwrap(), opts)
1078+
if special {
1079+
return msg, special
10701080
}
10711081
}
1072-
// If we got here, that means the error is not anything special. Just format
1073-
// it as is.
1082+
// If we got here, that means that the wrapped error chain does not have
1083+
// any special formatting below it. So we want to return the topmost non-special
1084+
// error (which is 'err')
10741085

10751086
// Default just printing the error. Use +v for verbose to handle stack
10761087
// traces of xerrors.
10771088
if opts.Verbose {
1078-
return pretty.Sprint(headLineStyle(), fmt.Sprintf("%+v", err))
1089+
return pretty.Sprint(headLineStyle(), fmt.Sprintf("%+v", err)), false
10791090
}
10801091

1081-
return pretty.Sprint(headLineStyle(), fmt.Sprintf("%v", err))
1092+
return pretty.Sprint(headLineStyle(), fmt.Sprintf("%v", err)), false
10821093
}
10831094

10841095
// formatMultiError formats a multi-error. It formats it as a list of errors.
@@ -1092,7 +1103,8 @@ func cliHumanFormatError(err error, opts *formatOpts) string {
10921103
func formatMultiError(multi []error, opts *formatOpts) string {
10931104
var errorStrings []string
10941105
for _, err := range multi {
1095-
errorStrings = append(errorStrings, cliHumanFormatError(err, opts))
1106+
msg, _ := cliHumanFormatError(err, opts)
1107+
errorStrings = append(errorStrings, msg)
10961108
}
10971109

10981110
// Write errors out
@@ -1126,7 +1138,7 @@ func formatRunCommandError(err *clibase.RunCommandError, opts *formatOpts) strin
11261138
var str strings.Builder
11271139
_, _ = str.WriteString(pretty.Sprint(headLineStyle(), fmt.Sprintf("Encountered an error running %q", err.Cmd.FullName())))
11281140

1129-
msgString := cliHumanFormatError(err.Err, opts)
1141+
msgString, _ := cliHumanFormatError(err.Err, opts)
11301142
_, _ = str.WriteString("\n")
11311143
_, _ = str.WriteString(pretty.Sprint(tailLineStyle(), msgString))
11321144
return str.String()

0 commit comments

Comments
 (0)