charmbracelet / bubbletea

A powerful little TUI framework 🏗
MIT License
25.9k stars 746 forks source link

Recover panics from within cmds goroutines #234

Open brooks-connor-a opened 2 years ago

brooks-connor-a commented 2 years ago

Panics are handled by recovering the panic and gracefully tearing down the Program. However goroutines started within the Program are outside the scope of the recover, and as such can end in the program terminating without properly tearing down. This can result in the terminal getting stuck in a non-interactive state until it is reset.

Here's a minimal reproduction:

package main
​
import ( 
    tea "github.com/charmbracelet/bubbletea"
)
​
type model struct {}

func (m model) Init() tea.Cmd {
    return nil
}

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { 
    return m, func() tea.Msg { 
        if true { 
            panic("")
        } 
        return tea.KeyEnter
    } 
}
​
func (m model) View() string { 
    return ""
}
​
func main() { 
    p := tea.NewProgram(model{})
    p.Start()
}
decentral1se commented 1 year ago

Thanks for reporting @brooks-connor-a, ran into this also.

(Firing up background Tor process, then panic, then it isn't cleaned up)

joerdav commented 9 months ago

I took a look at this, it seems like the best way to solve was to recover the panic and write to the errs channel. Happy for some feedback if it's not in the spirit of how bubbletea works.