feat(code): better errors and retry on login#2076
Conversation
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
apps/code/src/main/services/oauth/service.ts:452-492
**Missing tests for retry logic**
The custom rule for this repo requires comprehensive tests that verify the complete retry flow with multiple retry attempts when retry logic is introduced. This PR adds a 3-attempt retry loop with exponential backoff to `exchangeCodeForToken`, but no test file covering the new behavior is included. Specifically, scenarios worth testing include: network failure on all attempts (exhausts retries, throws with `NETWORK_ERROR_MESSAGE`), network failure on first attempt then success, 5xx on first attempt then success, and 4xx immediately throwing without retrying.
Reviews (1): Last reviewed commit: "feat(code): better erros and retry on lo..." | Re-trigger Greptile |
| for (let attempt = 0; attempt < TOKEN_FETCH_MAX_ATTEMPTS; attempt++) { | ||
| let response: Response; | ||
| try { | ||
| response = await fetch(`${cloudUrl}/oauth/token`, { | ||
| method: "POST", | ||
| headers: { "Content-Type": "application/json" }, | ||
| body, | ||
| }); | ||
| } catch (error) { | ||
| // fetch threw — DNS/TLS/socket failure. The raw message ("Failed to fetch", | ||
| // "fetch failed", "terminated", etc.) leaks to the UI as-is, so we replace | ||
| // it with something users can act on. | ||
| lastError = NETWORK_ERROR_MESSAGE; | ||
| log.warn("Token exchange network error", { | ||
| attempt, | ||
| error: error instanceof Error ? error.message : String(error), | ||
| }); | ||
| if (attempt === TOKEN_FETCH_MAX_ATTEMPTS - 1) break; | ||
| await sleepWithBackoff(attempt, TOKEN_FETCH_BACKOFF); | ||
| continue; | ||
| } | ||
|
|
||
| if (response.ok) { | ||
| return response.json(); | ||
| } | ||
|
|
||
| lastError = `Token exchange failed: ${response.status} ${response.statusText}`; | ||
| const isServerError = response.status >= 500; | ||
| if (!isServerError) { | ||
| throw new Error(lastError); | ||
| } | ||
|
|
||
| log.warn("Token exchange server error", { | ||
| attempt, | ||
| status: response.status, | ||
| }); | ||
| if (attempt === TOKEN_FETCH_MAX_ATTEMPTS - 1) break; | ||
| await sleepWithBackoff(attempt, TOKEN_FETCH_BACKOFF); | ||
| } | ||
|
|
||
| return response.json(); | ||
| throw new Error(lastError); |
There was a problem hiding this comment.
The custom rule for this repo requires comprehensive tests that verify the complete retry flow with multiple retry attempts when retry logic is introduced. This PR adds a 3-attempt retry loop with exponential backoff to exchangeCodeForToken, but no test file covering the new behavior is included. Specifically, scenarios worth testing include: network failure on all attempts (exhausts retries, throws with NETWORK_ERROR_MESSAGE), network failure on first attempt then success, 5xx on first attempt then success, and 4xx immediately throwing without retrying.
Rule Used: When implementing retry logic, include comprehensi... (source)
Learned From
PostHog/posthog#32651
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/code/src/main/services/oauth/service.ts
Line: 452-492
Comment:
**Missing tests for retry logic**
The custom rule for this repo requires comprehensive tests that verify the complete retry flow with multiple retry attempts when retry logic is introduced. This PR adds a 3-attempt retry loop with exponential backoff to `exchangeCodeForToken`, but no test file covering the new behavior is included. Specifically, scenarios worth testing include: network failure on all attempts (exhausts retries, throws with `NETWORK_ERROR_MESSAGE`), network failure on first attempt then success, 5xx on first attempt then success, and 4xx immediately throwing without retrying.
**Rule Used:** When implementing retry logic, include comprehensi... ([source](https://app.greptile.com/review/custom-context?memory=24d1be3f-07fb-465d-b1a7-60dff301aed8))
**Learned From**
[PostHog/posthog#32651](https://github.com/PostHog/posthog/pull/32651)
How can I resolve this? If you propose a fix, please make it concise.
Problem
When the OAuth token exchange request fails due to a network issue (DNS failure, TLS error, socket drop, etc.), the raw low-level error message (e.g. "Failed to fetch", "fetch failed", "terminated") was being surfaced directly to users with no actionable guidance. Additionally, transient network or server-side errors had no retry logic, meaning a single blip would immediately fail the login flow.
Changes