mirror of
https://github.com/mum4k/termdash.git
synced 2025-04-25 13:48:50 +08:00
Improving error handling.
This commit is contained in:
parent
220f979fa6
commit
09464a2db7
33
termdash.go
33
termdash.go
@ -58,11 +58,12 @@ func RedrawInterval(t time.Duration) Option {
|
||||
})
|
||||
}
|
||||
|
||||
// InputErrorHandler is used to provide a function that will be called with all
|
||||
// input event errors. If not provided, input event errors are discarded.
|
||||
func InputErrorHandler(f func(error)) Option {
|
||||
// ErrorHandler is used to provide a function that will be called with all
|
||||
// errors that occur while the dashboard is running. If not provided, any
|
||||
// errors panic the application.
|
||||
func ErrorHandler(f func(error)) Option {
|
||||
return option(func(td *termdash) {
|
||||
td.inputErrorHandler = f
|
||||
td.errorHandler = f
|
||||
})
|
||||
}
|
||||
|
||||
@ -119,7 +120,7 @@ type termdash struct {
|
||||
|
||||
// Options.
|
||||
redrawInterval time.Duration
|
||||
inputErrorHandler func(error)
|
||||
errorHandler func(error)
|
||||
mouseSubscriber func(*terminalapi.Mouse)
|
||||
keyboardSubscriber func(*terminalapi.Keyboard)
|
||||
}
|
||||
@ -140,11 +141,13 @@ func newTermdash(t terminalapi.Terminal, c *container.Container, opts ...Option)
|
||||
return td
|
||||
}
|
||||
|
||||
// inputError forwards the input error to the error handler if one was
|
||||
// provided.
|
||||
func (td *termdash) inputError(err error) {
|
||||
if td.inputErrorHandler != nil {
|
||||
td.inputErrorHandler(err)
|
||||
// handleError forwards the error to the error handler if one was
|
||||
// provided or panics.
|
||||
func (td *termdash) handleError(err error) {
|
||||
if td.errorHandler != nil {
|
||||
td.errorHandler(err)
|
||||
} else {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,12 +226,12 @@ func (td *termdash) processEvents(ctx context.Context) {
|
||||
switch ev := event.(type) {
|
||||
case *terminalapi.Keyboard:
|
||||
if err := td.keyEvRedraw(ev); err != nil {
|
||||
td.inputError(err)
|
||||
td.handleError(err)
|
||||
}
|
||||
|
||||
case *terminalapi.Mouse:
|
||||
if err := td.mouseEvRedraw(ev); err != nil {
|
||||
td.inputError(err)
|
||||
td.handleError(err)
|
||||
}
|
||||
|
||||
case *terminalapi.Resize:
|
||||
@ -240,7 +243,7 @@ func (td *termdash) processEvents(ctx context.Context) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
default:
|
||||
td.inputError(ev.Error())
|
||||
td.handleError(ev.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,10 +264,6 @@ func (td *termdash) start(ctx context.Context) error {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
if err := td.periodicRedraw(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// stops when stop() is called or the context expires.
|
||||
go td.processEvents(ctx)
|
||||
|
||||
|
@ -107,6 +107,7 @@ func TestRun(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
desc string
|
||||
size image.Point
|
||||
opts []Option
|
||||
events []terminalapi.Event
|
||||
// function to execute after the test case, can do additional comparison.
|
||||
@ -116,6 +117,7 @@ func TestRun(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
desc: "draws the dashboard until closed",
|
||||
size: image.Point{60, 10},
|
||||
opts: []Option{
|
||||
RedrawInterval(1),
|
||||
},
|
||||
@ -130,8 +132,21 @@ func TestRun(t *testing.T) {
|
||||
return ft
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "fails when the widget doesn't draw",
|
||||
size: image.Point{1, 1},
|
||||
opts: []Option{
|
||||
RedrawInterval(1),
|
||||
},
|
||||
want: func(size image.Point) *faketerm.Terminal {
|
||||
ft := faketerm.MustNew(size)
|
||||
return ft
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
desc: "resizes the terminal",
|
||||
size: image.Point{60, 10},
|
||||
opts: []Option{
|
||||
RedrawInterval(1),
|
||||
},
|
||||
@ -149,9 +164,9 @@ func TestRun(t *testing.T) {
|
||||
return ft
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
desc: "forwards mouse events to container",
|
||||
size: image.Point{60, 10},
|
||||
opts: []Option{
|
||||
RedrawInterval(1),
|
||||
},
|
||||
@ -174,6 +189,7 @@ func TestRun(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "forwards keyboard events to container",
|
||||
size: image.Point{60, 10},
|
||||
opts: []Option{
|
||||
RedrawInterval(1),
|
||||
},
|
||||
@ -195,30 +211,12 @@ func TestRun(t *testing.T) {
|
||||
return ft
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "ignores input errors without error handler",
|
||||
opts: []Option{
|
||||
RedrawInterval(1),
|
||||
},
|
||||
events: []terminalapi.Event{
|
||||
terminalapi.NewError("input error"),
|
||||
},
|
||||
want: func(size image.Point) *faketerm.Terminal {
|
||||
ft := faketerm.MustNew(size)
|
||||
|
||||
fakewidget.MustDraw(
|
||||
ft,
|
||||
testcanvas.MustNew(ft.Area()),
|
||||
widgetapi.Options{},
|
||||
)
|
||||
return ft
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "forwards input errors to the error handler",
|
||||
size: image.Point{60, 10},
|
||||
opts: []Option{
|
||||
RedrawInterval(1),
|
||||
InputErrorHandler(handler.handle),
|
||||
ErrorHandler(handler.handle),
|
||||
},
|
||||
events: []terminalapi.Event{
|
||||
terminalapi.NewError("input error"),
|
||||
@ -242,6 +240,7 @@ func TestRun(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "forwards keyboard events to the subscriber",
|
||||
size: image.Point{60, 10},
|
||||
opts: []Option{
|
||||
RedrawInterval(1),
|
||||
KeyboardSubscriber(keySub.receive),
|
||||
@ -272,6 +271,7 @@ func TestRun(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "forwards mouse events to the subscriber",
|
||||
size: image.Point{60, 10},
|
||||
opts: []Option{
|
||||
RedrawInterval(1),
|
||||
MouseSubscriber(mouseSub.receive),
|
||||
@ -313,7 +313,7 @@ func TestRun(t *testing.T) {
|
||||
eq.Push(ev)
|
||||
}
|
||||
|
||||
got, err := faketerm.New(image.Point{60, 10}, faketerm.WithEventQueue(eq))
|
||||
got, err := faketerm.New(tc.size, faketerm.WithEventQueue(eq))
|
||||
if err != nil {
|
||||
t.Fatalf("faketerm.New => unexpected error: %v", err)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user