From 76ce6694742e4199780b4eeb7aa8f72c7403e990 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 7 Oct 2022 21:48:50 +0200 Subject: [PATCH] chore: make CatchPanics an option flag --- options.go | 2 +- options_test.go | 11 ++++------- tea.go | 33 +++++++++++++++++---------------- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/options.go b/options.go index 3aad18c..8b4b4d4 100644 --- a/options.go +++ b/options.go @@ -52,7 +52,7 @@ func WithoutSignalHandler() ProgramOption { // cleanup on exit. func WithoutCatchPanics() ProgramOption { return func(p *Program) { - p.CatchPanics = false + p.startupOptions |= withoutCatchPanics } } diff --git a/options_test.go b/options_test.go index ba44410..7e08f58 100644 --- a/options_test.go +++ b/options_test.go @@ -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) { p := NewProgram(nil, WithoutRenderer()) switch p.renderer.(type) { @@ -62,6 +55,10 @@ func TestOptions(t *testing.T) { 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) { exercise(t, WithoutSignalHandler(), withoutSignalHandler) }) diff --git a/tea.go b/tea.go index 82afda5..75fa756 100644 --- a/tea.go +++ b/tea.go @@ -72,6 +72,12 @@ const ( withCustomInput withANSICompressor 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. @@ -88,26 +94,21 @@ type Program struct { errs chan error 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 - input io.Reader // this will usually be os.Stdin. - cancelReader cancelreader.CancelReader + renderer renderer + + // where to read inputs from, this will usually be os.Stdin. + input io.Reader + cancelReader cancelreader.CancelReader + console console.Console - renderer renderer 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 - console console.Console - // 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. // When the program exits this will be restored. @@ -133,7 +134,6 @@ func NewProgram(model Model, opts ...ProgramOption) *Program { initialModel: model, input: os.Stdin, msgs: make(chan Msg), - CatchPanics: true, killc: make(chan bool, 1), } @@ -383,7 +383,8 @@ func (p *Program) StartReturningModel() (Model, error) { close(sigintLoopDone) } - if p.CatchPanics { + // Recover from panics. + if !p.startupOptions.has(withoutCatchPanics) { defer func() { if r := recover(); r != nil { p.shutdown(true)