cliHumanFormatError formats an error for the CLI. Newlines and styling are included. The second return value is true if the error is special and the error chain has custom formatting applied. If you change this code, you can use the cli "example-errors" tool to verify all errors still look ok. go
(from string, err error, opts *formatOpts)
| 1346 | // |
| 1347 | //nolint:errorlint |
| 1348 | func cliHumanFormatError(from string, err error, opts *formatOpts) (string, bool) { |
| 1349 | if opts == nil { |
| 1350 | opts = &formatOpts{} |
| 1351 | } |
| 1352 | if err == nil { |
| 1353 | return "<nil>", true |
| 1354 | } |
| 1355 | |
| 1356 | if multi, ok := err.(interface{ Unwrap() []error }); ok { |
| 1357 | multiErrors := multi.Unwrap() |
| 1358 | if len(multiErrors) == 1 { |
| 1359 | // Format as a single error |
| 1360 | return cliHumanFormatError(from, multiErrors[0], opts) |
| 1361 | } |
| 1362 | return formatMultiError(from, multiErrors, opts), true |
| 1363 | } |
| 1364 | |
| 1365 | // First check for sentinel errors that we want to handle specially. |
| 1366 | // Order does matter! We want to check for the most specific errors first. |
| 1367 | if sdkError, ok := err.(*codersdk.Error); ok { |
| 1368 | return formatCoderSDKError(from, sdkError, opts), true |
| 1369 | } |
| 1370 | |
| 1371 | if cmdErr, ok := err.(*serpent.RunCommandError); ok { |
| 1372 | // no need to pass the "from" context to this since it is always |
| 1373 | // top level. We care about what is below this. |
| 1374 | return formatRunCommandError(cmdErr, opts), true |
| 1375 | } |
| 1376 | |
| 1377 | if uw, ok := err.(interface{ Unwrap() error }); ok { |
| 1378 | if unwrapped := uw.Unwrap(); unwrapped != nil { |
| 1379 | msg, special := cliHumanFormatError(from+traceError(err), unwrapped, opts) |
| 1380 | if special { |
| 1381 | return msg, special |
| 1382 | } |
| 1383 | } |
| 1384 | } |
| 1385 | // If we got here, that means that the wrapped error chain does not have |
| 1386 | // any special formatting below it. So we want to return the topmost non-special |
| 1387 | // error (which is 'err') |
| 1388 | |
| 1389 | // Default just printing the error. Use +v for verbose to handle stack |
| 1390 | // traces of xerrors. |
| 1391 | if opts.Verbose { |
| 1392 | return pretty.Sprint(headLineStyle(), fmt.Sprintf("%+v", err)), false |
| 1393 | } |
| 1394 | |
| 1395 | return pretty.Sprint(headLineStyle(), fmt.Sprintf("%v", err)), false |
| 1396 | } |
| 1397 | |
| 1398 | // formatMultiError formats a multi-error. It formats it as a list of errors. |
| 1399 | // |
no test coverage detected