yikart/AiToEarn · info · DOMException
Upload canceled
Error message
Upload canceled
What it means
enqueueUpload throws an AbortError DOMException named 'Upload canceled' when the user cancels a task between fingerprint computation (computeFileFingerprint) and registering the task's md5. The queue keeps a canceledTasks set keyed by taskId; at each async checkpoint it re-checks membership and aborts so a canceled file never proceeds to upload. This is a normal, user-initiated control-flow signal, not a fault.
Source
Thrown at project/aitoearn-web/src/components/PublishDialog/compoents/PublishManageUpload/usePublishManageUpload.ts:196
fileName: name,
size: file.size ?? 0,
type,
status: UploadTaskStatusEnum.Hashing,
progress: 0,
createdAt: Date.now(),
updatedAt: Date.now(),
},
},
}))
const promise = (async (): Promise<UploadResult> => {
let currentMd5: string | undefined
try {
const md5 = computeFileFingerprint(file, name)
currentMd5 = md5
if (canceledTasks.has(taskId)) {
throw new DOMException('Upload canceled', 'AbortError')
}
taskMd5Map.set(taskId, md5)
finalizeTask(taskId, {
md5,
status: UploadTaskStatusEnum.Pending,
})
const cache = get().md5Cache[md5]
if (cache) {
const result: UploadResult = { ...cache, fromCache: true }
finalizeTask(taskId, {
status: UploadTaskStatusEnum.Success,
progress: 100,
fromCache: true,
})
return resultView on GitHub (pinned to d3aa8bea5b)
Solutions
- Treat DOMException with name 'AbortError' and message 'Upload canceled' as an expected cancel signal: swallow it or update task state to 'canceled', do not surface it as an error toast.
- Ensure cancel actions set the task's UI status to canceled before/independent of the queue throwing, so the user sees consistent state.
- If you need the upload to proceed, do not add the taskId to canceledTasks; check membership only after the user confirms cancel.
- On unmount, clear pending tasks deliberately and suppress AbortError logging to avoid noisy console errors.
Example fix
// before
task.cancel = () => canceledTasks.add(taskId)
await enqueueUpload(file) // rejects with 'Upload canceled'
// after
try {
await enqueueUpload(file)
}
catch (e) {
if (e instanceof DOMException && e.name === 'AbortError') {
updateTaskStatus(taskId, 'canceled')
return
}
throw e
} Defensive patterns
Strategy: try-catch
Validate before calling
// no cheap pre-check: the cancel can land at any async checkpoint const isCanceled = (taskId: string) => canceledTasks.has(taskId) if (isCanceled(taskId)) return // skip enqueue entirely when already canceled
Type guard
function isAbortError(e: unknown): e is DOMException {
return e instanceof DOMException && e.name === 'AbortError'
} Try / catch
try {
await enqueueUpload(file)
}
catch (e) {
if (isAbortError(e)) { markTaskCanceled(taskId); return }
throw e
} Prevention
- Check canceledTasks before starting fingerprinting to skip already-canceled tasks cheaply
- Propagate an AbortSignal into computeFileFingerprint so cancellation aborts mid-hash
- Keep task UI state and canceledTasks in sync in one updateTaskCanceled helper
- Never log AbortError as an error level event; treat as user intent
When it happens
Trigger: Calling enqueueUpload and removing/canceling the task (adding its taskId to canceledTasks) while computeFileFingerprint(file, name) is still running, before taskMd5Map.set(taskId, md5) executes.
Common situations: User clicks remove/cancel on a file row in the publish manage upload list while the md5 fingerprint of a large file is being computed; rapid cancel after enqueue; component unmount cleanup canceling in-flight enqueues.
Related errors
- 上传已取消
- 上传已取消
- VideoUploadVidNotFound
- Relay uploadSign returned no uploadUrl: ${JSON.stringify(sig
- ChannelPlatformResponseInvalid
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/ddb51a0881137e95.
Report an issue: GitHub.