{"record":{"id":"c4b1149e698bd873","repo":"urfave/cli","slug":"v","errorCode":null,"errorMessage":"%+v","messagePattern":"%\\+v","errorType":"exception","errorClass":"exitError","httpStatus":null,"severity":"info","filePath":"errors.go","lineNumber":134,"sourceCode":"\ntype exitError struct {\n\texitCode int\n\terr      error\n}\n\n// Exit wraps a message and exit code into an error, which by default is\n// handled with a call to os.Exit during default error handling.\n//\n// This is the simplest way to trigger a non-zero exit code for a Command without\n// having to call os.Exit manually. During testing, this behavior can be avoided\n// by overriding the ExitErrHandler function on a Command or the package-global\n// OsExiter function.\nfunc Exit(message any, exitCode int) ExitCoder {\n\tvar err error\n\n\tswitch e := message.(type) {\n\tcase ErrorFormatter:\n\t\terr = fmt.Errorf(\"%+v\", message)\n\tcase error:\n\t\terr = e\n\tdefault:\n\t\terr = fmt.Errorf(\"%+v\", message)\n\t}\n\n\treturn &exitError{\n\t\terr:      err,\n\t\texitCode: exitCode,\n\t}\n}\n\nfunc (ee *exitError) Error() string {\n\treturn ee.err.Error()\n}\n\nfunc (ee *exitError) ExitCode() int {\n\treturn ee.exitCode","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/urfave/cli/blob/1a4deb4f5a35ee12706602698dc0527d44c14b19/errors.go#L116-L152","documentation":"cli.Exit builds an ExitCoder from a message and code. When the message is neither an error nor an ErrorFormatter, it is formatted with fmt.Errorf(\"%+v\", message), so the resulting error's text is the %+v rendering of whatever was passed (e.g. a struct dump).","triggerScenarios":"Calling cli.Exit with a non-error, non-ErrorFormatter value such as a struct, slice, or map; the message text is then '%+v' output rather than a human-readable string.","commonSituations":"Passing raw data structures to Exit instead of formatting them first; assuming Exit takes a string; refactors that change a string argument to a typed value.","solutions":["Pass a string or errors.New(...) as the message","If passing structured data, format it first with fmt.Sprintf(\"%v\", data)","Implement the ErrorFormatter interface so %+v yields a readable message"],"exampleFix":"// before\nreturn cli.Exit(myStruct, 1)\n// after\nreturn cli.Exit(fmt.Sprintf(\"invalid input: %v\", myStruct), 1)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func exitMsg(v any) error {\n    switch m := v.(type) {\n    case error:\n        return m\n    case fmt.Stringer:\n        return errors.New(m.String())\n    default:\n        return errors.New(fmt.Sprint(v))\n    }\n}","tryCatchPattern":"err := cli.Exit(msg, 1)\n// inspect what will be printed before exiting\nif !isUserReadable(fmt.Sprint(msg)) { msg = fmt.Sprintf(\"exit: %v\", msg) }","preventionTips":["Only pass string or error values to cli.Exit","Implement ErrorFormatter/Stringer for structured message types","Unit-test the rendered message of exit errors"],"tags":["go","cli","error-handling","exit-codes"],"backgroundTag":"unformatted-error-message","analyzedSha":"1a4deb4f5a35ee12706602698dc0527d44c14b19","analyzedAt":"2026-08-31T18:42:09.451Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}