on main help sign in
fix(tui): further guard against type accessor and map panics (#783)
commit15b989cfc7bc9eb4ecdd4eaf80def2b69f798388 authorChristian Rocha <christian@rocha.is> dateTue 26 Aug 2025, 16:41 (1 year ago) parent9bf5410
1 file changed+65−17
internal/tui/tui.go+65−17
internal/tui/tui.go+65−17
@@ -76,8 +76,13 @@ type appModel struct {
7676
7777// Init initializes the application model and returns initial commands.
7878func (a appModel) Init() tea.Cmd {
79+ item, ok := a.pages[a.currentPage]
80+ if !ok {
81+ return nil
82+ }
83+
7984 var cmds []tea.Cmd
80− cmd := a.pages[a.currentPage].Init()
85+ cmd := item.Init()
8186 cmds = append(cmds, cmd)
8287 a.loadedPages[a.currentPage] = true
8388
@@ -99,7 +104,10 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
99104 case tea.KeyboardEnhancementsMsg:
100105 for id, page := range a.pages {
101106 m, pageCmd := page.Update(msg)
102− a.pages[id] = m.(util.Model)
107+ if model, ok := m.(util.Model); ok {
108+ a.pages[id] = model
109+ }
110+
103111 if pageCmd != nil {
104112 cmds = append(cmds, pageCmd)
105113 }
@@ -114,7 +122,10 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
114122 case completions.OpenCompletionsMsg, completions.FilterCompletionsMsg,
115123 completions.CloseCompletionsMsg, completions.RepositionCompletionsMsg:
116124 u, completionCmd := a.completions.Update(msg)
117− a.completions = u.(completions.Completions)
125+ if model, ok := u.(completions.Completions); ok {
126+ a.completions = model
127+ }
128+
118129 return a, completionCmd
119130
120131 // Dialog messages
@@ -214,9 +225,12 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
214225 return a, nil
215226 }
216227
217− // forward to page
228+ // Forward to view.
218229 updated, itemCmd := item.Update(msg)
219− a.pages[a.currentPage] = updated.(util.Model)
230+ if model, ok := updated.(util.Model); ok {
231+ a.pages[a.currentPage] = model
232+ }
233+
220234 return a, itemCmd
221235 case pubsub.Event[permission.PermissionRequest]:
222236 return a, util.CmdHandler(dialogs.OpenDialogMsg{
@@ -241,7 +255,10 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
241255 // Forward agent events to dialogs
242256 if a.dialog.HasDialogs() && a.dialog.ActiveDialogID() == compact.CompactDialogID {
243257 u, dialogCmd := a.dialog.Update(payload)
244− a.dialog = u.(dialogs.DialogCmp)
258+ if model, ok := u.(dialogs.DialogCmp); ok {
259+ a.dialog = model
260+ }
261+
245262 cmds = append(cmds, dialogCmd)
246263 }
247264
@@ -270,7 +287,10 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
270287
271288 a.isConfigured = config.HasInitialDataConfig()
272289 updated, pageCmd := item.Update(msg)
273− a.pages[a.currentPage] = updated.(util.Model)
290+ if model, ok := updated.(util.Model); ok {
291+ a.pages[a.currentPage] = model
292+ }
293+
274294 cmds = append(cmds, pageCmd)
275295 return a, tea.Batch(cmds...)
276296
@@ -289,14 +309,20 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
289309 }
290310
291311 updated, pageCmd := item.Update(msg)
292− a.pages[a.currentPage] = updated.(util.Model)
312+ if model, ok := updated.(util.Model); ok {
313+ a.pages[a.currentPage] = model
314+ }
315+
293316 cmds = append(cmds, pageCmd)
294317 }
295318 return a, tea.Batch(cmds...)
296319 case tea.PasteMsg:
297320 if a.dialog.HasDialogs() {
298321 u, dialogCmd := a.dialog.Update(msg)
299− a.dialog = u.(dialogs.DialogCmp)
322+ if model, ok := u.(dialogs.DialogCmp); ok {
323+ a.dialog = model
324+ }
325+
300326 cmds = append(cmds, dialogCmd)
301327 } else {
302328 item, ok := a.pages[a.currentPage]
@@ -305,7 +331,10 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
305331 }
306332
307333 updated, pageCmd := item.Update(msg)
308− a.pages[a.currentPage] = updated.(util.Model)
334+ if model, ok := updated.(util.Model); ok {
335+ a.pages[a.currentPage] = model
336+ }
337+
309338 cmds = append(cmds, pageCmd)
310339 }
311340 return a, tea.Batch(cmds...)
@@ -317,12 +346,18 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
317346 if !ok {
318347 return a, nil
319348 }
349+
320350 updated, cmd := item.Update(msg)
321− a.pages[a.currentPage] = updated.(util.Model)
351+ if model, ok := updated.(util.Model); ok {
352+ a.pages[a.currentPage] = model
353+ }
322354
323355 if a.dialog.HasDialogs() {
324356 u, dialogCmd := a.dialog.Update(msg)
325− a.dialog = u.(dialogs.DialogCmp)
357+ if model, ok := u.(dialogs.DialogCmp); ok {
358+ a.dialog = model
359+ }
360+
326361 cmds = append(cmds, dialogCmd)
327362 }
328363 cmds = append(cmds, cmd)
@@ -332,27 +367,38 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
332367// handleWindowResize processes window resize events and updates all components.
333368func (a *appModel) handleWindowResize(width, height int) tea.Cmd {
334369 var cmds []tea.Cmd
370+
371+ // TODO: clean up these magic numbers.
335372 if a.showingFullHelp {
336373 height -= 5
337374 } else {
338375 height -= 2
339376 }
377+
340378 a.width, a.height = width, height
341379 // Update status bar
342380 s, cmd := a.status.Update(tea.WindowSizeMsg{Width: width, Height: height})
343− a.status = s.(status.StatusCmp)
381+ if model, ok := s.(status.StatusCmp); ok {
382+ a.status = model
383+ }
344384 cmds = append(cmds, cmd)
345385
346− // Update the current page
386+ // Update the current view.
347387 for p, page := range a.pages {
348388 updated, pageCmd := page.Update(tea.WindowSizeMsg{Width: width, Height: height})
349− a.pages[p] = updated.(util.Model)
389+ if model, ok := updated.(util.Model); ok {
390+ a.pages[p] = model
391+ }
392+
350393 cmds = append(cmds, pageCmd)
351394 }
352395
353396 // Update the dialogs
354397 dialog, cmd := a.dialog.Update(tea.WindowSizeMsg{Width: width, Height: height})
355− a.dialog = dialog.(dialogs.DialogCmp)
398+ if model, ok := dialog.(dialogs.DialogCmp); ok {
399+ a.dialog = model
400+ }
401+
356402 cmds = append(cmds, cmd)
357403
358404 return tea.Batch(cmds...)
@@ -443,7 +489,9 @@ func (a *appModel) handleKeyPressMsg(msg tea.KeyPressMsg) tea.Cmd {
443489 }
444490
445491 updated, cmd := item.Update(msg)
446− a.pages[a.currentPage] = updated.(util.Model)
492+ if model, ok := updated.(util.Model); ok {
493+ a.pages[a.currentPage] = model
494+ }
447495 return cmd
448496 }
449497}