Repository: charmbracelet/bubbletea

Issue #924: Application deadlock when initial model's init panics
Created: 2024-02-12T04:47:16Z
Describe the bug
With the current flow in *Program.Run(), the renderer isn't started until after the initial model has its .Init() function called. This currently causes an issue in the event that the initial model panics unexpectedly because the program is set to recover from panics, but can't finish shutting down because it's in a deadlock. I propose moving the p.renderer.start() to before the p.initialModel.Init() call in order to prevent this deadlock scenario. This will at least have the renderer start listening for a done signal on the context in the event of a panic.
I'm unsure if there are other unintended side effects from this change, but I don't see any from testing all of the examples.
To Reproduce
Running the code in the Source Code section will reproduce the issue. Instead of the expected panic being bubbled up, the app instead gets permanently stuck hanging waiting for
	// Stop the renderer before acquiring the mutex to avoid a deadlock.
	r.once.Do(func() {
		r.done <- struct{}{}
	})
to execute.
Source Code
package main

import tea "github.com/charmbracelet/bubbletea"

type model struct {
}

func (m model) Init() tea.Cmd {
	//TODO implement me
	panic("implement me")
}

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	//TODO implement me
	panic("implement me")
}

func (m model) View() string {
	//TODO implement me
	panic("implement me")
}

func main() {
	m := model{}
	if _, err := tea.NewProgram(m).Run(); err != nil {
		panic(err)
	}
}
Expected behavior
Caught panic:                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                                    
implement me                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                    
Restoring terminal...   
Additional context
I have a fork with a branch created with the proposed change here.

Duplicate issue #904: Application hang when calling panic
Created: 2024-01-17T16:34:09Z
Describe the bug
I have gotten my application to hang in a way that I can't get out of it without killing it from another terminal when calling panic while the application is initializing. If the application panics at a later time it exits properly.
Setup
Please complete the following information along with version numbers, if applicable.

OS - macOS Sonoma 14.2.1
Shell - zsh
Terminal Emulator - iterm2
Terminal Multiplexer - N/A

To Reproduce
Steps to reproduce the behavior:

Clone https://github.com/timmattison/bubbletea-hang
Run go run main2.go model.go
Kill the process from another terminal

Source Code
Source code is in linked repo
Expected behavior
I would expect that it panics and exits but instead gets stuck when trying to write to the done channel.

  
    
      bubbletea/standard_renderer.go
    
    
         Line 121
      in
      8f3464a
    
  
  
    

        
          
           r.done <- struct{}{}

Closing comment (2024-03-01T17:22:04Z): Closing as dupe of #924.