mum4k / termdash

Terminal based dashboard.
Apache License 2.0
2.69k stars 133 forks source link

panic: unknown tcell event type: <nil> #339

Open kmulvey opened 1 year ago

kmulvey commented 1 year ago

I get this error every time I try to quit (by pressing 'q'). It also leaves the terminal window in an unusable state. Where do i start debugging this? The stack trace doesnt even list any of my code.

       quitter := func(k *terminalapi.Keyboard) {
           if k.Key == 'q' || k.Key == 'Q' {
               term.Close()
           }
       }

Full code is here: https://github.com/kmulvey/text2speech/blob/main/dashboard.go

panic: unknown tcell event type: <nil>

goroutine 59 [running]:
github.com/mum4k/termdash.(*termdash).handleError(...)
    /opt/code/go/pkg/mod/github.com/mum4k/termdash@v0.17.0/termdash.go:252
github.com/mum4k/termdash.(*termdash).subscribers.func1({0xb61960?, 0xc000118010?})
    /opt/code/go/pkg/mod/github.com/mum4k/termdash@v0.17.0/termdash.go:215 +0xd2
github.com/mum4k/termdash/private/event.(*subscriber).callback(0xc00007e2c0, {0xb61960?, 0xc000118010?})
    /opt/code/go/pkg/mod/github.com/mum4k/termdash@v0.17.0/private/event/event.go:95 +0x31
github.com/mum4k/termdash/private/event.(*subscriber).run(0xc00007e2c0, {0xb66b18, 0xc00007e200})
    /opt/code/go/pkg/mod/github.com/mum4k/termdash@v0.17.0/private/event/event.go:110 +0x5a
created by github.com/mum4k/termdash/private/event.newSubscriber
    /opt/code/go/pkg/mod/github.com/mum4k/termdash@v0.17.0/private/event/event.go:89 +0x205
mum4k commented 1 year ago

I think the problem here is an invalid order of termination. The implemented quitter calls term.Close() thus closing the terminal object that was given to Termdash for use. This breaks the lifetime guarantee - objects given to called functions must outlive those function calls.

What happens is that the term object shuts down and becomes invalid. But there is some concurrency that still attempts to use it via termdash, probably in one of those goroutines.

The solution is to make sure that termdash and all goroutines are correctly terminated before the term object gets closed. Termination should be done in the exact opposite order of construction.

You can look at the demos for an example of a correct termination sequence, e.g. the termdashdemo:

https://github.com/mum4k/termdash/blob/master/termdashdemo/termdashdemo.go