@@ -77,10 +77,11 @@ type App struct {
7777 previousBlockedPRs map [string ]bool
7878 targetUser string
7979 cacheDir string
80+ authError string
81+ incoming []PR
8082 outgoing []PR
8183 lastMenuTitles []string
8284 pendingTurnResults []TurnResult
83- incoming []PR
8485 updateInterval time.Duration
8586 consecutiveFailures int
8687 mu sync.RWMutex
@@ -93,6 +94,52 @@ type App struct {
9394 enableAudioCues bool
9495}
9596
97+ func loadCurrentUser (ctx context.Context , app * App ) {
98+ log .Println ("Loading current user..." )
99+
100+ if app .client == nil {
101+ log .Println ("Skipping user load - no GitHub client available" )
102+ return
103+ }
104+
105+ var user * github.User
106+ err := retry .Do (func () error {
107+ var retryErr error
108+ user , _ , retryErr = app .client .Users .Get (ctx , "" )
109+ if retryErr != nil {
110+ log .Printf ("GitHub Users.Get failed (will retry): %v" , retryErr )
111+ return retryErr
112+ }
113+ return nil
114+ },
115+ retry .Attempts (maxRetries ),
116+ retry .DelayType (retry .BackOffDelay ),
117+ retry .MaxDelay (maxRetryDelay ),
118+ retry .OnRetry (func (n uint , err error ) {
119+ log .Printf ("GitHub Users.Get retry %d/%d: %v" , n + 1 , maxRetries , err )
120+ }),
121+ retry .Context (ctx ),
122+ )
123+ if err != nil {
124+ log .Printf ("Warning: Failed to load current user after %d retries: %v" , maxRetries , err )
125+ if app .authError == "" {
126+ app .authError = fmt .Sprintf ("Failed to load user: %v" , err )
127+ }
128+ return
129+ }
130+
131+ if user == nil {
132+ log .Print ("Warning: GitHub API returned nil user" )
133+ return
134+ }
135+
136+ app .currentUser = user
137+ // Log if we're using a different target user (sanitized)
138+ if app .targetUser != "" && app .targetUser != user .GetLogin () {
139+ log .Printf ("Querying PRs for user '%s' instead of authenticated user" , sanitizeForLog (app .targetUser ))
140+ }
141+ }
142+
96143func main () {
97144 // Parse command line flags
98145 var targetUser string
@@ -150,40 +197,13 @@ func main() {
150197 log .Println ("Initializing GitHub clients..." )
151198 err = app .initClients (ctx )
152199 if err != nil {
153- log .Fatalf ("Failed to initialize clients: %v" , err )
154- }
155-
156- log .Println ("Loading current user..." )
157- var user * github.User
158- err = retry .Do (func () error {
159- var retryErr error
160- user , _ , retryErr = app .client .Users .Get (ctx , "" )
161- if retryErr != nil {
162- log .Printf ("GitHub Users.Get failed (will retry): %v" , retryErr )
163- return retryErr
164- }
165- return nil
166- },
167- retry .Attempts (maxRetries ),
168- retry .DelayType (retry .BackOffDelay ),
169- retry .MaxDelay (maxRetryDelay ),
170- retry .OnRetry (func (n uint , err error ) {
171- log .Printf ("GitHub Users.Get retry %d/%d: %v" , n + 1 , maxRetries , err )
172- }),
173- retry .Context (ctx ),
174- )
175- if err != nil {
176- log .Fatalf ("Failed to load current user after %d retries: %v" , maxRetries , err )
177- }
178- if user == nil {
179- log .Fatal ("GitHub API returned nil user" )
200+ log .Printf ("Warning: Failed to initialize clients: %v" , err )
201+ app .authError = err .Error ()
202+ // Continue running with auth error - will show error in UI
180203 }
181- app .currentUser = user
182204
183- // Log if we're using a different target user (sanitized)
184- if app .targetUser != "" && app .targetUser != user .GetLogin () {
185- log .Printf ("Querying PRs for user '%s' instead of authenticated user" , sanitizeForLog (app .targetUser ))
186- }
205+ // Load current user if we have a client
206+ loadCurrentUser (ctx , app )
187207
188208 log .Println ("Starting systray..." )
189209 // Create a cancellable context for the application
@@ -199,16 +219,8 @@ func main() {
199219
200220func (app * App ) onReady (ctx context.Context ) {
201221 log .Println ("System tray ready" )
202- systray .SetTitle ("Loading PRs..." )
203222
204- // Set tooltip based on whether we're using a custom user
205- tooltip := "GitHub PR Monitor"
206- if app .targetUser != "" {
207- tooltip = fmt .Sprintf ("GitHub PR Monitor - @%s" , app .targetUser )
208- }
209- systray .SetTooltip (tooltip )
210-
211- // Set up click handlers
223+ // Set up click handlers first (needed for both success and error states)
212224 systray .SetOnClick (func (menu systray.IMenu ) {
213225 log .Println ("Icon clicked" )
214226 if menu != nil {
@@ -227,6 +239,26 @@ func (app *App) onReady(ctx context.Context) {
227239 }
228240 })
229241
242+ // Check if we have an auth error
243+ if app .authError != "" {
244+ systray .SetTitle ("⚠️" )
245+ systray .SetTooltip ("GitHub PR Monitor - Authentication Error" )
246+ // Create initial error menu
247+ app .rebuildMenu (ctx )
248+ // Clean old cache on startup
249+ app .cleanupOldCache ()
250+ return
251+ }
252+
253+ systray .SetTitle ("Loading PRs..." )
254+
255+ // Set tooltip based on whether we're using a custom user
256+ tooltip := "GitHub PR Monitor"
257+ if app .targetUser != "" {
258+ tooltip = fmt .Sprintf ("GitHub PR Monitor - @%s" , app .targetUser )
259+ }
260+ systray .SetTooltip (tooltip )
261+
230262 // Clean old cache on startup
231263 app .cleanupOldCache ()
232264
0 commit comments