Avoid showing panics directly if debug mode is not enabled
This commit is contained in:
		
							
								
								
									
										52
									
								
								gomuks.go
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								gomuks.go
									
									
									
									
									
								
							@@ -17,8 +17,10 @@
 | 
				
			|||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"path/filepath"
 | 
						"path/filepath"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"maunium.net/go/gomatrix"
 | 
						"maunium.net/go/gomatrix"
 | 
				
			||||||
	"maunium.net/go/gomuks/config"
 | 
						"maunium.net/go/gomuks/config"
 | 
				
			||||||
@@ -29,17 +31,18 @@ import (
 | 
				
			|||||||
	"maunium.net/go/tview"
 | 
						"maunium.net/go/tview"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type gomuks struct {
 | 
					type Gomuks struct {
 | 
				
			||||||
	app    *tview.Application
 | 
						app       *tview.Application
 | 
				
			||||||
	ui     *ui.GomuksUI
 | 
						ui        *ui.GomuksUI
 | 
				
			||||||
	matrix *matrix.Container
 | 
						matrix    *matrix.Container
 | 
				
			||||||
	debug  *debug.Pane
 | 
						debug     *debug.Pane
 | 
				
			||||||
	config *config.Config
 | 
						debugMode bool
 | 
				
			||||||
 | 
						config    *config.Config
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewGomuks(enableDebug bool) *gomuks {
 | 
					func NewGomuks(enableDebug bool) *Gomuks {
 | 
				
			||||||
	configDir := filepath.Join(os.Getenv("HOME"), ".config/gomuks")
 | 
						configDir := filepath.Join(os.Getenv("HOME"), ".config/gomuks")
 | 
				
			||||||
	gmx := &gomuks{
 | 
						gmx := &Gomuks{
 | 
				
			||||||
		app: tview.NewApplication(),
 | 
							app: tview.NewApplication(),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -63,13 +66,14 @@ func NewGomuks(enableDebug bool) *gomuks {
 | 
				
			|||||||
	main := gmx.ui.InitViews()
 | 
						main := gmx.ui.InitViews()
 | 
				
			||||||
	if enableDebug {
 | 
						if enableDebug {
 | 
				
			||||||
		main = gmx.debug.Wrap(main)
 | 
							main = gmx.debug.Wrap(main)
 | 
				
			||||||
 | 
							gmx.debugMode = true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	gmx.app.SetRoot(main, true)
 | 
						gmx.app.SetRoot(main, true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return gmx
 | 
						return gmx
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (gmx *gomuks) Stop() {
 | 
					func (gmx *Gomuks) Stop() {
 | 
				
			||||||
	gmx.debug.Print("Disconnecting from Matrix...")
 | 
						gmx.debug.Print("Disconnecting from Matrix...")
 | 
				
			||||||
	gmx.matrix.Stop()
 | 
						gmx.matrix.Stop()
 | 
				
			||||||
	gmx.debug.Print("Cleaning up UI...")
 | 
						gmx.debug.Print("Cleaning up UI...")
 | 
				
			||||||
@@ -78,44 +82,54 @@ func (gmx *gomuks) Stop() {
 | 
				
			|||||||
		gmx.debug.Print("Saving session...")
 | 
							gmx.debug.Print("Saving session...")
 | 
				
			||||||
		gmx.config.Session.Save()
 | 
							gmx.config.Session.Save()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						os.Exit(0)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (gmx *gomuks) Recover() {
 | 
					func (gmx *Gomuks) Recover() {
 | 
				
			||||||
	if p := recover(); p != nil {
 | 
						if p := recover(); p != nil {
 | 
				
			||||||
		if gmx.App().GetScreen() != nil {
 | 
							if gmx.App().GetScreen() != nil {
 | 
				
			||||||
			gmx.App().GetScreen().Fini()
 | 
								gmx.App().GetScreen().Fini()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		panic(p)
 | 
							if gmx.debugMode {
 | 
				
			||||||
 | 
								panic(p)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								debug.PrettyPanic()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (gmx *gomuks) Start() {
 | 
					func (gmx *Gomuks) Start() {
 | 
				
			||||||
	if err := gmx.app.Run(); err != nil {
 | 
						if err := gmx.app.Run(); err != nil {
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (gmx *gomuks) Matrix() *gomatrix.Client {
 | 
					func (gmx *Gomuks) Matrix() *gomatrix.Client {
 | 
				
			||||||
	return gmx.matrix.Client()
 | 
						return gmx.matrix.Client()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (gmx *gomuks) MatrixContainer() ifc.MatrixContainer {
 | 
					func (gmx *Gomuks) MatrixContainer() ifc.MatrixContainer {
 | 
				
			||||||
	return gmx.matrix
 | 
						return gmx.matrix
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (gmx *gomuks) App() *tview.Application {
 | 
					func (gmx *Gomuks) App() *tview.Application {
 | 
				
			||||||
	return gmx.app
 | 
						return gmx.app
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (gmx *gomuks) Config() *config.Config {
 | 
					func (gmx *Gomuks) Config() *config.Config {
 | 
				
			||||||
	return gmx.config
 | 
						return gmx.config
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (gmx *gomuks) UI() ifc.GomuksUI {
 | 
					func (gmx *Gomuks) UI() ifc.GomuksUI {
 | 
				
			||||||
	return gmx.ui
 | 
						return gmx.ui
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
	debug := os.Getenv("DEBUG")
 | 
						enableDebug := len(os.Getenv("DEBUG")) > 0
 | 
				
			||||||
	NewGomuks(len(debug) > 0).Start()
 | 
						NewGomuks(enableDebug).Start()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// We use os.Exit() everywhere, so exiting by returning from Start() shouldn't happen.
 | 
				
			||||||
 | 
						time.Sleep(5 * time.Second)
 | 
				
			||||||
 | 
						fmt.Println("Unexpected exit by return from Gomuks#Start().")
 | 
				
			||||||
 | 
						os.Exit(2)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -198,13 +198,13 @@ func (c *Container) HandleTyping(evt *gomatrix.Event) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Container) SendMessage(roomID, message string) {
 | 
					func (c *Container) SendMessage(roomID, message string) {
 | 
				
			||||||
	c.gmx.Recover()
 | 
						defer c.gmx.Recover()
 | 
				
			||||||
	c.SendTyping(roomID, false)
 | 
						c.SendTyping(roomID, false)
 | 
				
			||||||
	c.client.SendText(roomID, message)
 | 
						c.client.SendText(roomID, message)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Container) SendTyping(roomID string, typing bool) {
 | 
					func (c *Container) SendTyping(roomID string, typing bool) {
 | 
				
			||||||
	c.gmx.Recover()
 | 
						defer c.gmx.Recover()
 | 
				
			||||||
	ts := time.Now().Unix()
 | 
						ts := time.Now().Unix()
 | 
				
			||||||
	if c.typing > ts && typing {
 | 
						if c.typing > ts && typing {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,11 @@ package debug
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"io/ioutil"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"runtime/debug"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"maunium.net/go/tview"
 | 
						"maunium.net/go/tview"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -30,7 +35,7 @@ type Printer interface {
 | 
				
			|||||||
type Pane struct {
 | 
					type Pane struct {
 | 
				
			||||||
	*tview.TextView
 | 
						*tview.TextView
 | 
				
			||||||
	Height int
 | 
						Height int
 | 
				
			||||||
	num  int
 | 
						num    int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var Default Printer
 | 
					var Default Printer
 | 
				
			||||||
@@ -46,8 +51,8 @@ func NewPane() *Pane {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return &Pane{
 | 
						return &Pane{
 | 
				
			||||||
		TextView: pane,
 | 
							TextView: pane,
 | 
				
			||||||
		Height: 35,
 | 
							Height:   35,
 | 
				
			||||||
		num:  0,
 | 
							num:      0,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -81,3 +86,41 @@ func Print(text ...interface{}) {
 | 
				
			|||||||
		Default.Print(text...)
 | 
							Default.Print(text...)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Oops = ` __________
 | 
				
			||||||
 | 
					< Oh noes! >
 | 
				
			||||||
 | 
					 ‾‾‾\‾‾‾‾‾‾
 | 
				
			||||||
 | 
					     \   ^__^
 | 
				
			||||||
 | 
					      \  (XX)\_______
 | 
				
			||||||
 | 
					         (__)\       )\/\
 | 
				
			||||||
 | 
					          U  ||----W |
 | 
				
			||||||
 | 
					             ||     ||`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func PrettyPanic() {
 | 
				
			||||||
 | 
						fmt.Println(Oops)
 | 
				
			||||||
 | 
						fmt.Println("")
 | 
				
			||||||
 | 
						fmt.Println("A fatal error has occurred.")
 | 
				
			||||||
 | 
						fmt.Println("")
 | 
				
			||||||
 | 
						traceFile := fmt.Sprintf("/tmp/gomuks-panic-%s.txt", time.Now().Format("2006-01-02--15-04-05"))
 | 
				
			||||||
 | 
						data := debug.Stack()
 | 
				
			||||||
 | 
						err := ioutil.WriteFile(traceFile, data, 0644)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							fmt.Println("Saving the stack trace to", traceFile, "failed:")
 | 
				
			||||||
 | 
							fmt.Println("--------------------------------------------------------------------------------")
 | 
				
			||||||
 | 
							fmt.Println(err)
 | 
				
			||||||
 | 
							fmt.Println("--------------------------------------------------------------------------------")
 | 
				
			||||||
 | 
							fmt.Println("")
 | 
				
			||||||
 | 
							fmt.Println("You can file an issue at https://github.com/tulir/gomuks/issues.")
 | 
				
			||||||
 | 
							fmt.Println("Please provide the file save error (above) and the stack trace of the original error (below) when filing an issue.")
 | 
				
			||||||
 | 
							fmt.Println("")
 | 
				
			||||||
 | 
							fmt.Println("--------------------------------------------------------------------------------")
 | 
				
			||||||
 | 
							debug.PrintStack()
 | 
				
			||||||
 | 
							fmt.Println("--------------------------------------------------------------------------------")
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							fmt.Println("The stack trace has been saved to", traceFile)
 | 
				
			||||||
 | 
							fmt.Println("")
 | 
				
			||||||
 | 
							fmt.Println("You can file an issue at https://github.com/tulir/gomuks/issues.")
 | 
				
			||||||
 | 
							fmt.Println("Please provide the contents of that file when filing an issue.")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						os.Exit(1)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -148,7 +148,7 @@ func (view *MainView) InputDone(key tcell.Key) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (view *MainView) HandleCommand(room, command string, args []string) {
 | 
					func (view *MainView) HandleCommand(room, command string, args []string) {
 | 
				
			||||||
	view.gmx.Recover()
 | 
						defer view.gmx.Recover()
 | 
				
			||||||
	debug.Print("Handling command", command, args)
 | 
						debug.Print("Handling command", command, args)
 | 
				
			||||||
	switch command {
 | 
						switch command {
 | 
				
			||||||
	case "/quit":
 | 
						case "/quit":
 | 
				
			||||||
@@ -156,6 +156,8 @@ func (view *MainView) HandleCommand(room, command string, args []string) {
 | 
				
			|||||||
	case "/clearcache":
 | 
						case "/clearcache":
 | 
				
			||||||
		view.config.Session.Clear()
 | 
							view.config.Session.Clear()
 | 
				
			||||||
		view.gmx.Stop()
 | 
							view.gmx.Stop()
 | 
				
			||||||
 | 
						case "/panic":
 | 
				
			||||||
 | 
							panic("This is a test panic.")
 | 
				
			||||||
	case "/part":
 | 
						case "/part":
 | 
				
			||||||
		fallthrough
 | 
							fallthrough
 | 
				
			||||||
	case "/leave":
 | 
						case "/leave":
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user