aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gomuks.go52
-rw-r--r--matrix/matrix.go4
-rw-r--r--ui/debug/debug.go49
-rw-r--r--ui/view-main.go4
4 files changed, 84 insertions, 25 deletions
diff --git a/gomuks.go b/gomuks.go
index fecb67a..418fc9e 100644
--- a/gomuks.go
+++ b/gomuks.go
@@ -17,8 +17,10 @@
package main
import (
+ "fmt"
"os"
"path/filepath"
+ "time"
"maunium.net/go/gomatrix"
"maunium.net/go/gomuks/config"
@@ -29,17 +31,18 @@ import (
"maunium.net/go/tview"
)
-type gomuks struct {
- app *tview.Application
- ui *ui.GomuksUI
- matrix *matrix.Container
- debug *debug.Pane
- config *config.Config
+type Gomuks struct {
+ app *tview.Application
+ ui *ui.GomuksUI
+ matrix *matrix.Container
+ debug *debug.Pane
+ debugMode bool
+ config *config.Config
}
-func NewGomuks(enableDebug bool) *gomuks {
+func NewGomuks(enableDebug bool) *Gomuks {
configDir := filepath.Join(os.Getenv("HOME"), ".config/gomuks")
- gmx := &gomuks{
+ gmx := &Gomuks{
app: tview.NewApplication(),
}
@@ -63,13 +66,14 @@ func NewGomuks(enableDebug bool) *gomuks {
main := gmx.ui.InitViews()
if enableDebug {
main = gmx.debug.Wrap(main)
+ gmx.debugMode = true
}
gmx.app.SetRoot(main, true)
return gmx
}
-func (gmx *gomuks) Stop() {
+func (gmx *Gomuks) Stop() {
gmx.debug.Print("Disconnecting from Matrix...")
gmx.matrix.Stop()
gmx.debug.Print("Cleaning up UI...")
@@ -78,44 +82,54 @@ func (gmx *gomuks) Stop() {
gmx.debug.Print("Saving session...")
gmx.config.Session.Save()
}
+ os.Exit(0)
}
-func (gmx *gomuks) Recover() {
+func (gmx *Gomuks) Recover() {
if p := recover(); p != nil {
if gmx.App().GetScreen() != nil {
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 {
panic(err)
}
}
-func (gmx *gomuks) Matrix() *gomatrix.Client {
+func (gmx *Gomuks) Matrix() *gomatrix.Client {
return gmx.matrix.Client()
}
-func (gmx *gomuks) MatrixContainer() ifc.MatrixContainer {
+func (gmx *Gomuks) MatrixContainer() ifc.MatrixContainer {
return gmx.matrix
}
-func (gmx *gomuks) App() *tview.Application {
+func (gmx *Gomuks) App() *tview.Application {
return gmx.app
}
-func (gmx *gomuks) Config() *config.Config {
+func (gmx *Gomuks) Config() *config.Config {
return gmx.config
}
-func (gmx *gomuks) UI() ifc.GomuksUI {
+func (gmx *Gomuks) UI() ifc.GomuksUI {
return gmx.ui
}
func main() {
- debug := os.Getenv("DEBUG")
- NewGomuks(len(debug) > 0).Start()
+ enableDebug := len(os.Getenv("DEBUG")) > 0
+ 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)
}
diff --git a/matrix/matrix.go b/matrix/matrix.go
index 7652188..564dc81 100644
--- a/matrix/matrix.go
+++ b/matrix/matrix.go
@@ -198,13 +198,13 @@ func (c *Container) HandleTyping(evt *gomatrix.Event) {
}
func (c *Container) SendMessage(roomID, message string) {
- c.gmx.Recover()
+ defer c.gmx.Recover()
c.SendTyping(roomID, false)
c.client.SendText(roomID, message)
}
func (c *Container) SendTyping(roomID string, typing bool) {
- c.gmx.Recover()
+ defer c.gmx.Recover()
ts := time.Now().Unix()
if c.typing > ts && typing {
return
diff --git a/ui/debug/debug.go b/ui/debug/debug.go
index c855897..a87d64c 100644
--- a/ui/debug/debug.go
+++ b/ui/debug/debug.go
@@ -18,6 +18,11 @@ package debug
import (
"fmt"
+ "io/ioutil"
+ "os"
+ "time"
+
+ "runtime/debug"
"maunium.net/go/tview"
)
@@ -30,7 +35,7 @@ type Printer interface {
type Pane struct {
*tview.TextView
Height int
- num int
+ num int
}
var Default Printer
@@ -46,8 +51,8 @@ func NewPane() *Pane {
return &Pane{
TextView: pane,
- Height: 35,
- num: 0,
+ Height: 35,
+ num: 0,
}
}
@@ -81,3 +86,41 @@ func Print(text ...interface{}) {
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)
+}
diff --git a/ui/view-main.go b/ui/view-main.go
index 8ec482e..c2cd30f 100644
--- a/ui/view-main.go
+++ b/ui/view-main.go
@@ -148,7 +148,7 @@ func (view *MainView) InputDone(key tcell.Key) {
}
func (view *MainView) HandleCommand(room, command string, args []string) {
- view.gmx.Recover()
+ defer view.gmx.Recover()
debug.Print("Handling command", command, args)
switch command {
case "/quit":
@@ -156,6 +156,8 @@ func (view *MainView) HandleCommand(room, command string, args []string) {
case "/clearcache":
view.config.Session.Clear()
view.gmx.Stop()
+ case "/panic":
+ panic("This is a test panic.")
case "/part":
fallthrough
case "/leave":