1
0
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:
Jakub Sobon 2018-05-07 21:30:38 +01:00
parent 220f979fa6
commit 09464a2db7
No known key found for this signature in database
GPG Key ID: F2451A77FB05D3B7
2 changed files with 38 additions and 39 deletions

View File

@ -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)

View File

@ -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)
}