feat: add auto-retry (3 attempts) for file uploads on flaky connections

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matt
2026-04-07 20:10:52 -04:00
parent 97d7f9b625
commit 158eba416d

View File

@@ -166,26 +166,46 @@ export function RequirementUploadSlot({
requirementId: requirement.id,
})
// Upload file with progress tracking
await new Promise<void>((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.upload.addEventListener('progress', (event) => {
if (event.lengthComputable) {
setProgress(Math.round((event.loaded / event.total) * 100))
}
})
xhr.addEventListener('load', () => {
if (xhr.status >= 200 && xhr.status < 300) {
resolve()
// Upload file with progress tracking and auto-retry
const maxRetries = 3
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
await new Promise<void>((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.upload.addEventListener('progress', (event) => {
if (event.lengthComputable) {
setProgress(Math.round((event.loaded / event.total) * 100))
}
})
xhr.addEventListener('load', () => {
if (xhr.status >= 200 && xhr.status < 300) {
resolve()
} else {
reject(new Error(`Upload failed with status ${xhr.status}`))
}
})
xhr.addEventListener('error', () =>
reject(new Error('Network error during upload'))
)
xhr.addEventListener('abort', () =>
reject(new Error('Upload was aborted'))
)
xhr.open('PUT', url)
xhr.setRequestHeader('Content-Type', file.type)
xhr.send(file)
})
break // Success — exit retry loop
} catch (uploadErr) {
if (attempt < maxRetries) {
const delay = attempt * 2000
toast.info(`Upload interrupted, retrying... (${attempt}/${maxRetries})`)
setProgress(0)
await new Promise((r) => setTimeout(r, delay))
} else {
reject(new Error(`Upload failed with status ${xhr.status}`))
throw uploadErr
}
})
xhr.addEventListener('error', () => reject(new Error('Upload failed')))
xhr.open('PUT', url)
xhr.setRequestHeader('Content-Type', file.type)
xhr.send(file)
})
}
}
// Save metadata
await saveFileMetadata.mutateAsync({