chore: make CatchPanics an option flag

This commit is contained in:
Christian Muehlhaeuser 2022-10-07 21:48:50 +02:00
parent 0ac6702e11
commit 76ce669474
3 changed files with 22 additions and 24 deletions

View File

@ -52,7 +52,7 @@ func WithoutSignalHandler() ProgramOption {
// cleanup on exit. // cleanup on exit.
func WithoutCatchPanics() ProgramOption { func WithoutCatchPanics() ProgramOption {
return func(p *Program) { return func(p *Program) {
p.CatchPanics = false p.startupOptions |= withoutCatchPanics
} }
} }

View File

@ -25,13 +25,6 @@ func TestOptions(t *testing.T) {
} }
}) })
t.Run("catch panics", func(t *testing.T) {
p := NewProgram(nil, WithoutCatchPanics())
if p.CatchPanics {
t.Errorf("catch panics should not have been set")
}
})
t.Run("renderer", func(t *testing.T) { t.Run("renderer", func(t *testing.T) {
p := NewProgram(nil, WithoutRenderer()) p := NewProgram(nil, WithoutRenderer())
switch p.renderer.(type) { switch p.renderer.(type) {
@ -62,6 +55,10 @@ func TestOptions(t *testing.T) {
exercise(t, WithANSICompressor(), withANSICompressor) exercise(t, WithANSICompressor(), withANSICompressor)
}) })
t.Run("without catch panics", func(t *testing.T) {
exercise(t, WithoutCatchPanics(), withoutCatchPanics)
})
t.Run("without signal handler", func(t *testing.T) { t.Run("without signal handler", func(t *testing.T) {
exercise(t, WithoutSignalHandler(), withoutSignalHandler) exercise(t, WithoutSignalHandler(), withoutSignalHandler)
}) })

31
tea.go
View File

@ -72,6 +72,12 @@ const (
withCustomInput withCustomInput
withANSICompressor withANSICompressor
withoutSignalHandler withoutSignalHandler
// Catching panics is incredibly useful for restoring the terminal to a
// usable state after a panic occurs. When this is set, Bubble Tea will
// recover from panics, print the stack trace, and disable raw mode. This
// feature is on by default.
withoutCatchPanics
) )
// Program is a terminal user interface. // Program is a terminal user interface.
@ -88,26 +94,21 @@ type Program struct {
errs chan error errs chan error
readLoopDone chan struct{} readLoopDone chan struct{}
output *termenv.Output // where to send output. this will usually be os.Stdout. // where to send output, this will usually be os.Stdout.
output *termenv.Output
restoreOutput func() error restoreOutput func() error
input io.Reader // this will usually be os.Stdin.
cancelReader cancelreader.CancelReader
renderer renderer renderer renderer
// where to read inputs from, this will usually be os.Stdin.
input io.Reader
cancelReader cancelreader.CancelReader
console console.Console
altScreenWasActive bool // was the altscreen active before releasing the terminal? altScreenWasActive bool // was the altscreen active before releasing the terminal?
// CatchPanics is incredibly useful for restoring the terminal to a usable
// state after a panic occurs. When this is set, Bubble Tea will recover
// from panics, print the stack trace, and disable raw mode. This feature
// is on by default.
CatchPanics bool
ignoreSignals bool ignoreSignals bool
killc chan bool killc chan bool
console console.Console
// Stores the original reference to stdin for cases where input is not a // Stores the original reference to stdin for cases where input is not a
// TTY on windows and we've automatically opened CONIN$ to receive input. // TTY on windows and we've automatically opened CONIN$ to receive input.
// When the program exits this will be restored. // When the program exits this will be restored.
@ -133,7 +134,6 @@ func NewProgram(model Model, opts ...ProgramOption) *Program {
initialModel: model, initialModel: model,
input: os.Stdin, input: os.Stdin,
msgs: make(chan Msg), msgs: make(chan Msg),
CatchPanics: true,
killc: make(chan bool, 1), killc: make(chan bool, 1),
} }
@ -383,7 +383,8 @@ func (p *Program) StartReturningModel() (Model, error) {
close(sigintLoopDone) close(sigintLoopDone)
} }
if p.CatchPanics { // Recover from panics.
if !p.startupOptions.has(withoutCatchPanics) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
p.shutdown(true) p.shutdown(true)