diff --git a/cmd/server/main.go b/cmd/server/main.go index b58c68f882..5c2687e02b 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -42,7 +42,12 @@ import ( // main entry point for the web server func main() { app := buildCLI() - _ = app.Run(os.Args) + err := app.Run(os.Args) + if err != nil { + // An unhandled error was returned, wrap it and run it through the default exit code handler. Any errors + // that make it here should be caught further up the call stack and wrapped with cli.Exit and the proper exit code. + cli.HandleExitCoder(cli.Exit(fmt.Sprintf("Unexpected error encountered: %v.", err), 9)) + } } // buildCLI is the main entry point for the web server @@ -88,7 +93,7 @@ func buildCLI() *cli.App { cfg, err := cfgProvider.GetConfig() if err != nil { - return err + return cli.Exit(err, 1) } opts := []server_options.ServerOption{ diff --git a/cmd/server/main_test.go b/cmd/server/main_test.go new file mode 100644 index 0000000000..706265451d --- /dev/null +++ b/cmd/server/main_test.go @@ -0,0 +1,50 @@ +package main + +import ( + "bytes" + "strconv" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/urfave/cli/v2" +) + +func TestExitCodesWorkProperly(t *testing.T) { + testcases := []struct { + arguments []string + expectedExitCode int + expectedText string + }{ + {arguments: []string{}, expectedExitCode: 0, expectedText: "USAGE"}, + {arguments: []string{"--config", "/tmp/doesnotexist123", "start"}, expectedExitCode: 1, expectedText: "no config files found"}, + } + + cli.OsExiter = func(int) {} + for idx, tc := range testcases { + t.Run(strconv.Itoa(idx), func(t *testing.T) { + tc := tc + + c := buildCLI() + c.ExitErrHandler = func(_ *cli.Context, err error) {} + + var buf bytes.Buffer + c.Writer = &buf + c.ErrWriter = &buf + + args := append([]string{"./ui-server"}, tc.arguments...) + err := c.Run(args) + + if tc.expectedExitCode != 0 { + assert.Error(t, err) + } + + if err != nil { + ec := err.(cli.ExitCoder) + assert.Equal(t, tc.expectedExitCode, ec.ExitCode()) + assert.Contains(t, ec.Error(), tc.expectedText) + } else { + assert.Contains(t, buf.String(), tc.expectedText) + } + }) + } +}