logging: added a log on panic

Since panics still regularly "destroy" the terminal, it is hard to get a
stack trace for panics you do not anticipate. This commit adds a panic
handler that automatically creates a logfile inside the current working
directory.

It has to be added to every goroutine that is started and will repair
the terminal on a panic.

Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
Moritz Poldrack 2022-03-22 09:52:27 +01:00 committed by Robin Jarry
parent feecc09b73
commit ae83373fa6
27 changed files with 161 additions and 23 deletions

View file

@ -5,6 +5,7 @@ import (
"regexp"
"strings"
"git.sr.ht/~rjarry/aerc/logging"
"git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/widgets"
"git.sr.ht/~sircmpwn/getopt"
@ -52,7 +53,11 @@ func (Compose) Execute(aerc *widgets.Aerc, args []string) error {
}
tab.Content.Invalidate()
})
go composer.AppendContents(strings.NewReader(body))
go func() {
defer logging.PanicHandler()
composer.AppendContents(strings.NewReader(body))
}()
return nil
}

View file

@ -8,6 +8,7 @@ import (
"path/filepath"
"git.sr.ht/~rjarry/aerc/commands"
"git.sr.ht/~rjarry/aerc/logging"
"git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/widgets"
"git.sr.ht/~sircmpwn/getopt"
@ -111,7 +112,11 @@ func (Recover) Execute(aerc *widgets.Aerc, args []string) error {
tab.Name = subject
tab.Content.Invalidate()
})
go composer.AppendContents(bytes.NewReader(data))
go func() {
defer logging.PanicHandler()
composer.AppendContents(bytes.NewReader(data))
}()
// remove file if force flag is set
if force {

View file

@ -8,6 +8,7 @@ import (
"github.com/miolini/datacounter"
"github.com/pkg/errors"
"git.sr.ht/~rjarry/aerc/logging"
"git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/widgets"
"git.sr.ht/~rjarry/aerc/worker/types"
@ -66,6 +67,8 @@ func (Postpone) Execute(aerc *widgets.Aerc, args []string) error {
// run this as a goroutine so we can make other progress. The message
// will be saved once the directory is created.
go func() {
defer logging.PanicHandler()
errStr := <-errChan
if errStr != "" {
aerc.PushError(errStr)

View file

@ -16,6 +16,7 @@ import (
"github.com/pkg/errors"
"git.sr.ht/~rjarry/aerc/lib"
"git.sr.ht/~rjarry/aerc/logging"
"git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/widgets"
"git.sr.ht/~rjarry/aerc/worker/types"
@ -100,6 +101,8 @@ func (Send) Execute(aerc *widgets.Aerc, args []string) error {
failCh := make(chan error)
//writer
go func() {
defer logging.PanicHandler()
var sender io.WriteCloser
switch ctx.scheme {
case "smtp":
@ -131,6 +134,8 @@ func (Send) Execute(aerc *widgets.Aerc, args []string) error {
//cleanup + copy to sent
go func() {
defer logging.PanicHandler()
err = <-failCh
if err != nil {
aerc.PushError(strings.ReplaceAll(err.Error(), "\n", " "))

View file

@ -7,6 +7,7 @@ import (
"os/exec"
"time"
"git.sr.ht/~rjarry/aerc/logging"
"git.sr.ht/~rjarry/aerc/widgets"
)
@ -45,6 +46,8 @@ func (ExecCmd) Execute(aerc *widgets.Aerc, args []string) error {
cmd.Env = env
go func() {
defer logging.PanicHandler()
err := cmd.Run()
if err != nil {
aerc.PushError(err.Error())

View file

@ -8,6 +8,7 @@ import (
"time"
"git.sr.ht/~rjarry/aerc/commands"
"git.sr.ht/~rjarry/aerc/logging"
"git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/widgets"
"git.sr.ht/~rjarry/aerc/worker/types"
@ -94,6 +95,8 @@ func (Archive) Execute(aerc *widgets.Aerc, args []string) error {
}
// we need to do that in the background, else we block the main thread
go func() {
defer logging.PanicHandler()
wg.Wait()
if success {
aerc.PushStatus("Messages archived.", 10*time.Second)

View file

@ -9,6 +9,7 @@ import (
"time"
"git.sr.ht/~rjarry/aerc/commands"
"git.sr.ht/~rjarry/aerc/logging"
"git.sr.ht/~rjarry/aerc/widgets"
"git.sr.ht/~rjarry/aerc/worker/types"
@ -89,6 +90,8 @@ func (Pipe) Execute(aerc *widgets.Aerc, args []string) error {
return
}
go func() {
defer logging.PanicHandler()
defer pipe.Close()
io.Copy(pipe, reader)
}()
@ -146,6 +149,8 @@ func (Pipe) Execute(aerc *widgets.Aerc, args []string) error {
})
go func() {
defer logging.PanicHandler()
select {
case <-done:
break

View file

@ -8,6 +8,7 @@ import (
"git.sr.ht/~sircmpwn/getopt"
"git.sr.ht/~rjarry/aerc/lib"
"git.sr.ht/~rjarry/aerc/logging"
"git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/widgets"
"git.sr.ht/~rjarry/aerc/worker/types"
@ -169,6 +170,8 @@ func (FlagMsg) Execute(aerc *widgets.Aerc, args []string) error {
// We need to do flagging in the background, else we block the main thread
go func() {
defer logging.PanicHandler()
wg.Wait()
if success {
aerc.PushStatus(actionName+" flag '"+flagName+"' successful", 10*time.Second)

View file

@ -9,6 +9,7 @@ import (
"time"
"git.sr.ht/~rjarry/aerc/lib"
"git.sr.ht/~rjarry/aerc/logging"
"git.sr.ht/~rjarry/aerc/widgets"
)
@ -66,6 +67,8 @@ func (Open) Execute(aerc *widgets.Aerc, args []string) error {
return
}
go func() {
defer logging.PanicHandler()
err := xdg.Wait()
if err != nil {
aerc.PushError(err.Error())

View file

@ -13,6 +13,7 @@ import (
"github.com/mitchellh/go-homedir"
"git.sr.ht/~rjarry/aerc/commands"
"git.sr.ht/~rjarry/aerc/logging"
"git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/widgets"
)
@ -126,6 +127,8 @@ func (Save) Execute(aerc *widgets.Aerc, args []string) error {
// we need to wait for the callback prior to displaying a result
go func() {
defer logging.PanicHandler()
err := <-ch
if err != nil {
aerc.PushError(fmt.Sprintf("Save failed: %v", err))

View file

@ -13,6 +13,7 @@ import (
"github.com/lithammer/fuzzysearch/fuzzy"
"git.sr.ht/~rjarry/aerc/lib"
"git.sr.ht/~rjarry/aerc/logging"
"git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/widgets"
"github.com/gdamore/tcell/v2"
@ -51,6 +52,8 @@ func QuickTerm(aerc *widgets.Aerc, args []string, stdin io.Reader) (*widgets.Ter
status := make(chan error, 1)
go func() {
defer logging.PanicHandler()
_, err := io.Copy(pipe, stdin)
defer pipe.Close()
status <- err