From 213ebc57fb09ac0159ea18af0f32d1b1cc1ac9b2 Mon Sep 17 00:00:00 2001 From: Ben Schumacher Date: Tue, 2 Jul 2024 13:58:37 +0200 Subject: [PATCH] Print panic message when mmctl panics (#27390) --- server/cmd/mmctl/commands/root.go | 24 +++++++++++++++++++++--- server/cmd/mmctl/commands/root_test.go | 13 +++++++++++++ server/cmd/mmctl/printer/printer.go | 8 ++++---- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/server/cmd/mmctl/commands/root.go b/server/cmd/mmctl/commands/root.go index 32ce53307f5..bbaedfb27b4 100644 --- a/server/cmd/mmctl/commands/root.go +++ b/server/cmd/mmctl/commands/root.go @@ -4,6 +4,8 @@ package commands import ( + "fmt" + "net/url" "os" "path/filepath" "runtime/debug" @@ -56,10 +58,9 @@ func Run(args []string) error { defer func() { if x := recover(); x != nil { - printer.PrintError("Uh oh! Something unexpected happened :( Would you mind reporting it?\n") - printer.PrintError(`https://github.com/mattermost/mmctl/issues/new?title=%5Bbug%5D%20panic%20on%20mmctl%20v` + Version + "&body=%3C!---%20Please%20provide%20the%20stack%20trace%20--%3E\n") - printer.PrintError(string(debug.Stack())) + printPanic(x) + _ = printer.Flush() os.Exit(1) } }() @@ -67,6 +68,23 @@ func Run(args []string) error { return RootCmd.Execute() } +func printPanic(x any) { + u, err := url.Parse("https://github.com/mattermost/mattermost/issues/new") + if err != nil { + panic(err) + } + + q := u.Query() + q.Add("title", "[mmctl] [bug] panic on v"+Version) + q.Add("body", "\n") + u.RawQuery = q.Encode() + + printer.PrintError("Uh oh! Something unexpected happened :( Would you mind reporting it?") + printer.PrintError(u.String() + "\n") + printer.PrintError(fmt.Sprintf("%s", x)) + printer.PrintError(string(debug.Stack())) +} + var RootCmd = &cobra.Command{ Use: "mmctl", Short: "Remote client for the Open Source, self-hosted Slack-alternative", diff --git a/server/cmd/mmctl/commands/root_test.go b/server/cmd/mmctl/commands/root_test.go index e4040df95c8..cf07474f02e 100644 --- a/server/cmd/mmctl/commands/root_test.go +++ b/server/cmd/mmctl/commands/root_test.go @@ -7,8 +7,11 @@ import ( "bytes" "fmt" "strings" + "testing" + "github.com/mattermost/mattermost/server/v8/cmd/mmctl/printer" "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" ) func executeRawCommand(root *cobra.Command, args string) (c *cobra.Command, output string, err error) { @@ -20,6 +23,16 @@ func executeRawCommand(root *cobra.Command, args string) (c *cobra.Command, outp return c, actual.String(), err } +func TestRootRecover(t *testing.T) { + printPanic("some panic") + + lines := printer.GetErrorLines() + assert.Equal(t, "Uh oh! Something unexpected happened :( Would you mind reporting it?", lines[0]) + assert.True(t, strings.HasPrefix(lines[1], "https://github.com/mattermost/mattermost/issues/new?body=")) + assert.Equal(t, "some panic", lines[2]) + assert.True(t, strings.HasPrefix(lines[3], "goroutine ")) +} + func (s *MmctlUnitTestSuite) TestArgumentsHaveWhitespaceTrimmed() { arguments := []string{"value_1", "value_2"} lineEndings := []string{"\n", "\r", "\r\n"} diff --git a/server/cmd/mmctl/printer/printer.go b/server/cmd/mmctl/printer/printer.go index e5a1c498007..183c743cc30 100644 --- a/server/cmd/mmctl/printer/printer.go +++ b/server/cmd/mmctl/printer/printer.go @@ -33,7 +33,7 @@ type Printer struct { //nolint pager bool Quiet bool Lines []interface{} - ErrorLines []interface{} + ErrorLines []string cmd *cobra.Command serverAddr string @@ -193,7 +193,7 @@ func Flush() error { defer func() { printer.Lines = []interface{}{} - printer.ErrorLines = []interface{}{} + printer.ErrorLines = []string{} }() if cmd == nil || cmd.Name() != "list" || printer.cmd.Parent().Name() == "auth" { @@ -232,7 +232,7 @@ func Flush() error { // Clean resets the printer's accumulated lines func Clean() { printer.Lines = []interface{}{} - printer.ErrorLines = []interface{}{} + printer.ErrorLines = []string{} } // GetLines returns the printer's accumulated lines @@ -241,7 +241,7 @@ func GetLines() []interface{} { } // GetErrorLines returns the printer's accumulated error lines -func GetErrorLines() []interface{} { +func GetErrorLines() []string { return printer.ErrorLines }