From a9c6485fb00dbf2e4b55351c1ae74d4eaca3eec9 Mon Sep 17 00:00:00 2001 From: Jeff Halter <868228+jhalter@users.noreply.github.com> Date: Mon, 30 Jun 2025 15:24:19 -0700 Subject: Replace inappropriate panic calls with proper error handling - Convert panic in news article processing to return error instead - Replace panic in API stats endpoint with HTTP error response - Update ThreadedNewsMgr interface to return errors from ListArticles - Ensure server stability by handling errors gracefully --- hotline/news.go | 13 ++++++------- internal/mobius/api.go | 3 ++- internal/mobius/threaded_news.go | 2 +- internal/mobius/transaction_handlers.go | 5 ++++- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/hotline/news.go b/hotline/news.go index a490a89..c61a76f 100644 --- a/hotline/news.go +++ b/hotline/news.go @@ -14,7 +14,7 @@ var ( ) type ThreadedNewsMgr interface { - ListArticles(newsPath []string) NewsArtListData + ListArticles(newsPath []string) (NewsArtListData, error) GetArticle(newsPath []string, articleID uint32) *NewsArtData DeleteArticle(newsPath []string, articleID uint32, recursive bool) error PostArticle(newsPath []string, parentArticleID uint32, article NewsArtData) error @@ -41,7 +41,7 @@ type NewsCategoryListData15 struct { readOffset int // Internal offset to track read progress } -func (newscat *NewsCategoryListData15) GetNewsArtListData() NewsArtListData { +func (newscat *NewsCategoryListData15) GetNewsArtListData() (NewsArtListData, error) { var newsArts []NewsArtList var newsArtsPayload []byte @@ -70,8 +70,7 @@ func (newscat *NewsCategoryListData15) GetNewsArtListData() NewsArtListData { for _, v := range newsArts { b, err := io.ReadAll(&v) if err != nil { - // TODO - panic(err) + return NewsArtListData{}, err } newsArtsPayload = append(newsArtsPayload, b...) } @@ -81,7 +80,7 @@ func (newscat *NewsCategoryListData15) GetNewsArtListData() NewsArtListData { Name: []byte{}, Description: []byte{}, NewsArtList: newsArtsPayload, - } + }, nil } // NewsArtData represents an individual news article. @@ -242,10 +241,10 @@ type MockThreadNewsMgr struct { mock.Mock } -func (m *MockThreadNewsMgr) ListArticles(newsPath []string) NewsArtListData { +func (m *MockThreadNewsMgr) ListArticles(newsPath []string) (NewsArtListData, error) { args := m.Called(newsPath) - return args.Get(0).(NewsArtListData) + return args.Get(0).(NewsArtListData), args.Error(1) } func (m *MockThreadNewsMgr) GetArticle(newsPath []string, articleID uint32) *NewsArtData { diff --git a/internal/mobius/api.go b/internal/mobius/api.go index 4dfc575..0a20d01 100644 --- a/internal/mobius/api.go +++ b/internal/mobius/api.go @@ -263,7 +263,8 @@ func (srv *APIServer) ReloadHandler(reloadFunc func()) func(w http.ResponseWrite func (srv *APIServer) RenderStats(w http.ResponseWriter, _ *http.Request) { u, err := json.Marshal(srv.hlServer.CurrentStats()) if err != nil { - panic(err) + http.Error(w, "failed to marshal stats", http.StatusInternalServerError) + return } _, _ = w.Write(u) diff --git a/internal/mobius/threaded_news.go b/internal/mobius/threaded_news.go index e9d9c22..67e8282 100644 --- a/internal/mobius/threaded_news.go +++ b/internal/mobius/threaded_news.go @@ -195,7 +195,7 @@ func (n *ThreadedNewsYAML) DeleteArticle(newsPath []string, articleID uint32, _ return n.writeFile() } -func (n *ThreadedNewsYAML) ListArticles(newsPath []string) hotline.NewsArtListData { +func (n *ThreadedNewsYAML) ListArticles(newsPath []string) (hotline.NewsArtListData, error) { n.mu.Lock() defer n.mu.Unlock() diff --git a/internal/mobius/transaction_handlers.go b/internal/mobius/transaction_handlers.go index d8c4cb5..5181e15 100644 --- a/internal/mobius/transaction_handlers.go +++ b/internal/mobius/transaction_handlers.go @@ -1319,7 +1319,10 @@ func HandleGetNewsArtNameList(cc *hotline.ClientConn, t *hotline.Transaction) (r return res } - nald := cc.Server.ThreadedNewsMgr.ListArticles(pathStrs) + nald, err := cc.Server.ThreadedNewsMgr.ListArticles(pathStrs) + if err != nil { + return res + } b, err := io.ReadAll(&nald) if err != nil { -- cgit