@@ -2,6 +2,7 @@ package slack
22
33import (
44 "context"
5+ "errors"
56 "fmt"
67 "log/slog"
78 "strings"
@@ -37,10 +38,38 @@ func NewHomeHandler(
3738
3839// HandleAppHomeOpened updates the app home view when a user opens it.
3940func (h * HomeHandler ) HandleAppHomeOpened (ctx context.Context , teamID , slackUserID string ) error {
40- slog .Debug ("handling app home opened" ,
41+ slog .Info ("handling app home opened - fetching fresh data " ,
4142 "team_id" , teamID ,
4243 "slack_user_id" , slackUserID )
4344
45+ // Try up to 2 times - first with cached client, second with fresh client after invalid_auth
46+ for attempt := 0 ; attempt < 2 ; attempt ++ {
47+ if attempt > 0 {
48+ slog .Info ("retrying home view after invalid_auth" , "team_id" , teamID , "attempt" , attempt + 1 )
49+ }
50+
51+ err := h .tryHandleAppHomeOpened (ctx , teamID , slackUserID )
52+ if err == nil {
53+ return nil
54+ }
55+
56+ // If invalid_auth and first attempt, invalidate cache and retry
57+ if strings .Contains (err .Error (), "invalid_auth" ) && attempt == 0 {
58+ slog .Warn ("invalid_auth detected - invalidating cache and retrying" ,
59+ "team_id" , teamID )
60+ h .slackManager .InvalidateCache (teamID )
61+ continue
62+ }
63+
64+ // Other errors or second attempt - return immediately
65+ return err
66+ }
67+
68+ return errors .New ("failed after retries" )
69+ }
70+
71+ // tryHandleAppHomeOpened attempts to handle app home opened event.
72+ func (h * HomeHandler ) tryHandleAppHomeOpened (ctx context.Context , teamID , slackUserID string ) error {
4473 // Get Slack client for this workspace
4574 slackClient , err := h .slackManager .Client (ctx , teamID )
4675 if err != nil {
@@ -50,8 +79,12 @@ func (h *HomeHandler) HandleAppHomeOpened(ctx context.Context, teamID, slackUser
5079 // Get Slack user info to extract email
5180 slackUser , err := slackClient .API ().GetUserInfo (slackUserID )
5281 if err != nil {
82+ // Don't mask invalid_auth errors - let them propagate for retry logic
83+ if strings .Contains (err .Error (), "invalid_auth" ) {
84+ return fmt .Errorf ("failed to get Slack user info: %w" , err )
85+ }
5386 slog .Warn ("failed to get Slack user info" , "user_id" , slackUserID , "error" , err )
54- return h .publishPlaceholderHome (slackClient , slackUserID )
87+ return h .publishPlaceholderHome (ctx , slackClient , slackUserID )
5588 }
5689
5790 // Extract GitHub username from email (simple heuristic: part before @)
@@ -62,15 +95,15 @@ func (h *HomeHandler) HandleAppHomeOpened(ctx context.Context, teamID, slackUser
6295 slog .Warn ("could not extract GitHub username from Slack email" ,
6396 "slack_user_id" , slackUserID ,
6497 "email" , email )
65- return h .publishPlaceholderHome (slackClient , slackUserID )
98+ return h .publishPlaceholderHome (ctx , slackClient , slackUserID )
6699 }
67100 githubUsername := email [:atIndex ]
68101
69102 // Get all orgs for this workspace
70103 workspaceOrgs := h .workspaceOrgs (teamID )
71104 if len (workspaceOrgs ) == 0 {
72105 slog .Warn ("no workspace orgs found" , "team_id" , teamID )
73- return h .publishPlaceholderHome (slackClient , slackUserID )
106+ return h .publishPlaceholderHome (ctx , slackClient , slackUserID )
74107 }
75108
76109 // Get GitHub client for first org (they all share the same app)
@@ -92,7 +125,7 @@ func (h *HomeHandler) HandleAppHomeOpened(ctx context.Context, teamID, slackUser
92125 slog .Error ("failed to fetch dashboard" ,
93126 "github_user" , githubUsername ,
94127 "error" , err )
95- return h .publishPlaceholderHome (slackClient , slackUserID )
128+ return h .publishPlaceholderHome (ctx , slackClient , slackUserID )
96129 }
97130
98131 // Add workspace orgs to dashboard for UI display
@@ -102,15 +135,17 @@ func (h *HomeHandler) HandleAppHomeOpened(ctx context.Context, teamID, slackUser
102135 blocks := home .BuildBlocks (dashboard , workspaceOrgs [0 ])
103136
104137 // Publish to Slack
105- if err := slackClient .PublishHomeView (slackUserID , blocks ); err != nil {
138+ if err := slackClient .PublishHomeView (ctx , slackUserID , blocks ); err != nil {
106139 return fmt .Errorf ("failed to publish home view: %w" , err )
107140 }
108141
109- slog .Info ("published home view" ,
142+ slog .Info ("published home view with fresh data " ,
110143 "slack_user_id" , slackUserID ,
111144 "github_user" , githubUsername ,
112145 "incoming_prs" , len (dashboard .IncomingPRs ),
146+ "incoming_blocked" , dashboard .Counts ().IncomingBlocked ,
113147 "outgoing_prs" , len (dashboard .OutgoingPRs ),
148+ "outgoing_blocked" , dashboard .Counts ().OutgoingBlocked ,
114149 "workspace_orgs" , len (workspaceOrgs ))
115150
116151 return nil
@@ -137,7 +172,7 @@ func (h *HomeHandler) workspaceOrgs(teamID string) []string {
137172}
138173
139174// publishPlaceholderHome publishes a simple placeholder home view.
140- func (* HomeHandler ) publishPlaceholderHome (slackClient * Client , slackUserID string ) error {
175+ func (* HomeHandler ) publishPlaceholderHome (ctx context. Context , slackClient * Client , slackUserID string ) error {
141176 slog .Debug ("publishing placeholder home" , "user_id" , slackUserID )
142177
143178 blocks := home .BuildBlocks (& home.Dashboard {
@@ -146,5 +181,5 @@ func (*HomeHandler) publishPlaceholderHome(slackClient *Client, slackUserID stri
146181 WorkspaceOrgs : []string {"your-org" },
147182 }, "your-org" )
148183
149- return slackClient .PublishHomeView (slackUserID , blocks )
184+ return slackClient .PublishHomeView (ctx , slackUserID , blocks )
150185}
0 commit comments