OUT-3667: retry transient Dropbox 5xx and wrap getDropboxFileMetadata#98
Conversation
…adata Sentry DROPBOX-INTEGRATION-G surfaces a transient Dropbox 504 from DropboxWebhook.getDropboxFileMetadata because the call wasn't wrapped in retry, and withRetry's retryable set excluded 502/503/504. Broaden the retryable codes and route filesGetMetadata through withRetry. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR broadens The refactoring of Confidence Score: 5/5This PR is safe to merge — changes are well-scoped, semantically correct, and the 409 recovery path is unaffected. No logic bugs found. The RETRYABLE_STATUS_CODES refactoring is semantically equivalent to the old per-status comparisons. The withRetry wrapping on getDropboxFileMetadata correctly propagates non-retryable errors (409) so the existing catch-based recovery still works. Backoff parameters match the existing DropboxClient pattern. No files require special attention. Important Files Changed
Sequence DiagramsequenceDiagram
participant WS as DropboxWebhook
participant WR as withRetry
participant DBX as Dropbox API
WS->>WR: getDropboxFileMetadata(filePath)
loop up to 3 retries
WR->>DBX: filesGetMetadata({ path })
alt 5xx (500/502/503/504)
DBX-->>WR: DropboxResponseError (retryable)
WR->>WR: shouldRetry → true
WR->>WR: exponential backoff (3s→6s→12s)
else 429 + Retry-After header
DBX-->>WR: DropboxResponseError (rate limited)
WR->>WR: sleep(retryAfter * 1000)
WR->>WR: shouldRetry → true
else 409 (path moved / conflict)
DBX-->>WR: DropboxResponseError 409
WR->>WR: shouldRetry → false
WR-->>WS: throw DropboxResponseError(409)
WS->>WS: catch → dbxRootId lookup recovery
else 2xx success
DBX-->>WR: FileMetadata
WR-->>WS: FileMetadata
end
end
note over WR: All retries exhausted → throws terminal error
Reviews (1): Last reviewed commit: "fix(OUT-3667): retry transient Dropbox 5..." | Re-trigger Greptile |
Changes
withRetryretryable status codes to include502,503,504alongside the existing429and500. Centralized into aRETRYABLE_STATUS_CODESset soshouldRetryandonFailedAttemptshare one source of truth.DropboxWebhook.getDropboxFileMetadata'sfilesGetMetadatacall inwithRetry(3s/12s backoff, matchingDropboxClient's wrapped methods).Sentry DROPBOX-INTEGRATION-G — recurring
DropboxResponseError: Response failed with a 504 codefrom the webhook hot path. The 504 is a transient Dropbox upstream blip; before this PR it surfaced because the call wasn't wrapped, and even if it were, our retry policy ignored gateway-level codes.Testing Criteria
pnpm typecheckpassespnpm lintpasseshandleDbxRootPathMovestill works — 409 is not in the retryable set, so pRetry throws on first attempt and the existingcatchrecovers viadbxRootIdlookup. Worth a manual confirmation in staging by simulating a renamed root folder.Notes
Impact & Surface Area of Change
withRetryis shared byDropboxClient.{downloadFile, uploadFile, getAllFilesFolders}and nowgetDropboxFileMetadata. All four will now retry on 502/503/504. Verify no regression on the bidirectional sync path under partial Dropbox availability.Follow-up (separate ticket)
getDropboxFileMetadataintoDropboxClientso retry wiring lives next to the other wrapped SDK calls. A// Refactor below code...marker is in place at the call site.