From 990020617eeac9ef3e4fb21786ae51bd17fc5a2d Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Sun, 17 May 2026 04:51:46 +0000 Subject: [PATCH] fix: surface sync errors in UI and fix nil resp dereference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SyncBranchWithUpstreamRepo previously accessed resp.StatusCode before checking err, causing a nil pointer panic on transport-level failures. Fix by checking err first, then resp.StatusCode within the error branch. item.errMsg was populated on sync failure but never used in Title() or Description(), so failed syncs silently showed as selected (●) instead of error (⨯) while the title still said "Synchronization Done". Now both Title() and Description() check errMsg so users see the error icon and the reason the sync failed. Fixes #30 Co-authored-by: Thet Naing Tun --- internal/synrk/synrk.go | 11 +++++------ internal/ui/item.go | 7 ++++++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/internal/synrk/synrk.go b/internal/synrk/synrk.go index deaef89..8e4338b 100644 --- a/internal/synrk/synrk.go +++ b/internal/synrk/synrk.go @@ -70,14 +70,13 @@ func (c *concrete) GetForks(ctx context.Context) ([]*RepositoryWithDetails, erro func (c *concrete) SyncBranchWithUpstreamRepo(repo *RepositoryWithDetails) error { request := &github.RepoMergeUpstreamRequest{Branch: &repo.DefaultBranch} - res, resp, err := c.client.Repositories.MergeUpstream(context.Background(), repo.Owner, repo.Name, request) - - if resp.StatusCode == http.StatusConflict { - return fmt.Errorf("couldn't merge with upstream %s branch due to conflict", res.GetBaseBranch()) - } + _, resp, err := c.client.Repositories.MergeUpstream(context.Background(), repo.Owner, repo.Name, request) if err != nil { - return fmt.Errorf("couldn't merge with upstream %s branch: %w", res.GetBaseBranch(), err) + if resp != nil && resp.StatusCode == http.StatusConflict { + return fmt.Errorf("couldn't merge with upstream %s branch due to conflict", repo.DefaultBranch) + } + return fmt.Errorf("couldn't merge with upstream %s branch: %w", repo.DefaultBranch, err) } return nil diff --git a/internal/ui/item.go b/internal/ui/item.go index ea6f77e..37391b8 100644 --- a/internal/ui/item.go +++ b/internal/ui/item.go @@ -28,7 +28,7 @@ func (i item) Title() string { return iconSynced + " " + titleStr } - if !i.synced && i.repo.Error != nil { + if !i.synced && (i.repo.Error != nil || i.errMsg != "") { return errorStyle.Render(iconSyncFailed + " " + titleStr) } @@ -50,6 +50,11 @@ func (i item) Description() string { return errorStyle.Copy().PaddingLeft(2).Render(msg) } + if i.errMsg != "" { + msg := base + " fail to sync with " + upstream + fmt.Sprintf(" (%s)", i.errMsg) + return errorStyle.Copy().PaddingLeft(2).Render(msg) + } + if !i.synced { upstream = fmt.Sprintf("%s:%s", repo.Parent, repo.DefaultBranch) msg := fmt.Sprintf("%s is %d commit%s behind %s", base, repo.BehindBy, mayBePlural(repo.BehindBy), upstream)