-
Notifications
You must be signed in to change notification settings - Fork 48
fix: Improve error reporting #180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -160,11 +160,13 @@ func main() { | |
| _, err := parser.Parse() | ||
| // check for help flag | ||
| if err != nil { | ||
| if flagErr, ok := err.(*flags.Error); ok && flagErr.Type != flags.ErrHelp { | ||
| parser.WriteHelp(os.Stdout) | ||
| if flagErr, ok := err.(*flags.Error); ok && flagErr.Type == flags.ErrHelp { | ||
| os.Exit(0) | ||
| } | ||
|
|
||
| os.Exit(0) | ||
| // For actual errors, print help and exit with error code | ||
| fmt.Fprintf(os.Stderr, "Error: %s\n\n", err) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reason: treat real CLI parse errors as failures (exit 1 + stderr) so scripts can detect them; help requests should still be a clean exit. |
||
| parser.WriteHelp(os.Stderr) | ||
| os.Exit(1) | ||
| } | ||
|
|
||
| // no subcommand or help flag, run the TUI | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -251,7 +251,7 @@ func (c Commands) fetchAllFeeds() ([]store.Item, []ErrorItem, error) { | |
|
|
||
| err := c.store.UpsertItem(&i) | ||
| if err != nil { | ||
| log.Fatalf("[commands.go] fetchAllFeeds: %e", err) | ||
| log.Printf("[commands.go] fetchAllFeeds: failed to upsert item: %v", err) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid crashing the entire refresh on a single bad item; log the upsert failure and keep processing the rest.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid crashing the whole app on a single item upsert; log and continue so other feeds still load. |
||
| continue | ||
| } | ||
|
|
||
|
|
@@ -381,7 +381,9 @@ func htmlToMd(html string) string { | |
|
|
||
| mdown, err := converter.ConvertString(html) | ||
| if err != nil { | ||
| log.Fatal(err) | ||
| log.Printf("[commands.go] htmlToMd: failed to convert HTML to markdown: %v", err) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If HTML→Markdown conversion fails, log and fall back to raw HTML so the entry still renders instead of killing the app. |
||
| // Return the original HTML if conversion fails | ||
| return html | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If HTML->MD conversion fails, fall back to original HTML instead of exiting so users still see content. |
||
| } | ||
|
|
||
| return mdown | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -84,7 +84,7 @@ func (d itemDelegate) Render(w io.Writer, m list.Model, index int, listItem list | |
| func (m *model) UpdateList() tea.Cmd { | ||
| fs, err := m.commands.GetAllFeeds() | ||
| if err != nil { | ||
| return tea.Quit | ||
| return m.list.NewStatusMessage(fmt.Sprintf("Error: %s", err)) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Show a status message instead of quitting so users see why feeds failed to load.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace tea.Quit with a visible status message to avoid silent exits and keep the TUI responsive. |
||
| } | ||
|
|
||
| cmd := m.list.SetItems(convertItems(fs)) | ||
|
|
@@ -211,7 +211,7 @@ func updateList(msg tea.Msg, m model) (tea.Model, tea.Cmd) { | |
| current := item.(TUIItem) | ||
| err := m.commands.store.ToggleRead(current.ID) | ||
| if err != nil { | ||
| return m, tea.Quit | ||
| return m, m.list.NewStatusMessage(fmt.Sprintf("Error marking read: %s", err)) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Keep the TUI alive on toggle-read errors; report the problem in the status area. |
||
| } | ||
|
|
||
| cmds = append(cmds, m.UpdateList()) | ||
|
|
@@ -249,7 +249,7 @@ func updateList(msg tea.Msg, m model) (tea.Model, tea.Cmd) { | |
| current := item.(TUIItem) | ||
| err := m.commands.store.ToggleFavourite(current.ID) | ||
| if err != nil { | ||
| return m, tea.Quit | ||
| return m, m.list.NewStatusMessage(fmt.Sprintf("Error toggling favourite: %s", err)) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same rationale as toggle-read: show an error message instead of exiting the session. |
||
| } | ||
|
|
||
| cmds = append(cmds, m.UpdateList()) | ||
|
|
@@ -308,8 +308,8 @@ func updateList(msg tea.Msg, m model) (tea.Model, tea.Cmd) { | |
|
|
||
| content, err := m.commands.GetGlamourisedArticle(*m.selectedArticle) | ||
| if err != nil { | ||
| // LKS: there should be an error message here | ||
| return m, tea.Quit | ||
| m.selectedArticle = nil | ||
| return m, m.list.NewStatusMessage(fmt.Sprintf("Error opening article: %s", err)) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If rendering fails, clear selection and display an error to avoid leaving the UI stuck in the article view. |
||
| } | ||
|
|
||
| m.viewport.SetContent(content) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -98,7 +98,8 @@ func (m model) OpenLink(url string) tea.Cmd { | |
| for _, o := range m.cfg.Openers { | ||
| match, err := regexp.MatchString(o.Regex, url) | ||
| if err != nil { | ||
| return tea.Quit | ||
| log.Printf("[tui.go] OpenLink: invalid regex pattern: %v", err) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Skip invalid opener regex patterns with a log so a single bad config entry doesn't terminate the UI.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Invalid opener regex shouldn't kill the UI; log and skip this opener instead. |
||
| continue | ||
| } | ||
|
|
||
| if match { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -42,7 +42,8 @@ func updateViewport(msg tea.Msg, m model) (tea.Model, tea.Cmd) { | |
| case key.Matches(msg, ViewportKeyMap.OpenInBrowser): | ||
| current, err := m.commands.store.GetItemByID(*m.selectedArticle) | ||
| if err != nil { | ||
| return m, nil | ||
| m.selectedArticle = nil | ||
| return m, m.list.NewStatusMessage("Error: failed to get article") | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When the selected item can't be fetched, reset selection and show an error so the user can continue.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the selected article can't be loaded, clear selection and surface an error instead of silently failing. |
||
| } | ||
|
|
||
| it := ItemToTUIItem(current) | ||
|
|
@@ -52,11 +53,13 @@ func updateViewport(msg tea.Msg, m model) (tea.Model, tea.Cmd) { | |
| case key.Matches(msg, ViewportKeyMap.Favourite): | ||
| current, err := m.commands.store.GetItemByID(*m.selectedArticle) | ||
| if err != nil { | ||
| return m, nil | ||
| m.selectedArticle = nil | ||
| return m, m.list.NewStatusMessage("Error: failed to get article") | ||
| } | ||
| err = m.commands.store.ToggleFavourite(current.ID) | ||
| if err != nil { | ||
| return m, tea.Quit | ||
| m.selectedArticle = nil | ||
| return m, m.list.NewStatusMessage("Error toggling favourite") | ||
| } | ||
|
|
||
| case key.Matches(msg, ViewportKeyMap.Read): | ||
|
|
@@ -65,11 +68,13 @@ func updateViewport(msg tea.Msg, m model) (tea.Model, tea.Cmd) { | |
| } | ||
| current, err := m.commands.store.GetItemByID(*m.selectedArticle) | ||
| if err != nil { | ||
| return m, nil | ||
| m.selectedArticle = nil | ||
| return m, m.list.NewStatusMessage("Error: failed to get article") | ||
| } | ||
| err = m.commands.store.ToggleRead(current.ID) | ||
| if err != nil { | ||
| return m, tea.Quit | ||
| m.selectedArticle = nil | ||
| return m, m.list.NewStatusMessage("Error marking read") | ||
| } | ||
|
|
||
| if !m.commands.config.ShowRead { | ||
|
|
@@ -93,7 +98,8 @@ func updateViewport(msg tea.Msg, m model) (tea.Model, tea.Cmd) { | |
| // trigger refresh to update read indication | ||
| content, err := m.commands.GetGlamourisedArticle(*m.selectedArticle) | ||
| if err != nil { | ||
| return m, tea.Quit | ||
| m.selectedArticle = nil | ||
| return m, m.list.NewStatusMessage("Error rendering article") | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Render failures now surface as status messages instead of quitting, improving error visibility and resilience. |
||
| } | ||
| m.viewport.SetContent(content) | ||
|
|
||
|
|
@@ -111,7 +117,8 @@ func updateViewport(msg tea.Msg, m model) (tea.Model, tea.Cmd) { | |
|
|
||
| content, err := m.commands.GetGlamourisedArticle(*m.selectedArticle) | ||
| if err != nil { | ||
| return m, tea.Quit | ||
| m.selectedArticle = nil | ||
| return m, m.list.NewStatusMessage("Error rendering article") | ||
| } | ||
|
|
||
| m.viewport.SetContent(content) | ||
|
|
@@ -134,7 +141,8 @@ func updateViewport(msg tea.Msg, m model) (tea.Model, tea.Cmd) { | |
|
|
||
| content, err := m.commands.GetGlamourisedArticle(*m.selectedArticle) | ||
| if err != nil { | ||
| return m, tea.Quit | ||
| m.selectedArticle = nil | ||
| return m, m.list.NewStatusMessage("Error rendering article") | ||
| } | ||
|
|
||
| m.viewport.SetContent(content) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When flag parsing fails (non-help), surface the error on stderr, show help, and exit non-zero so CLI failures are visible to users/scripts.