yikart/AiToEarn · info · DOMException
上传已取消
Error message
上传已取消
What it means
optimizeImageForUpload honors an AbortSignal so callers can cancel pre-upload image optimization. If options.signal.aborted is already true when the function starts, it throws DOMException('上传已取消', 'AbortError') instead of doing wasted compression work.
Source
Thrown at project/aitoearn-web/src/utils/media.ts:159
if (typeof File === 'undefined')
return null
if (file instanceof File)
return file
return new File([file], getUploadImageFileName(file), {
type: getCompressionFileType(file.type),
lastModified: Date.now(),
})
}
/** 上传前优化图片:超过 1MB 的 jpeg/png/webp 会限制最长边并尽量压缩到 1MB 内 */
export async function optimizeImageForUpload(file: File | Blob, options?: OptimizeImageForUploadOptions) {
if (!shouldOptimizeImageForUpload(file) || typeof window === 'undefined')
return file
if (options?.signal?.aborted)
throw new DOMException('上传已取消', 'AbortError')
const compressionFile = toImageCompressionFile(file)
if (!compressionFile)
return file
try {
const { default: imageCompression } = await import('browser-image-compression')
const compressionOptions: ImageCompressionOptions = {
maxSizeMB: IMAGE_UPLOAD_MAX_SIZE_MB,
maxWidthOrHeight: IMAGE_UPLOAD_MAX_WIDTH_OR_HEIGHT,
initialQuality: IMAGE_UPLOAD_INITIAL_QUALITY,
useWebWorker: false,
fileType: getCompressionFileType(compressionFile.type),
signal: options?.signal,
}
const compressedFile = await imageCompression(compressionFile, compressionOptions)
return compressedFile.size < file.size ? compressedFile : fileView on GitHub (pinned to d3aa8bea5b)
Solutions
- Treat DOMException with name 'AbortError' as an expected cancellation: swallow it or update UI to 'cancelled', don't show it as an error
- Check signal.aborted in the caller before invoking uploadFile if cancellation is possible
- Create a fresh AbortController for each upload instead of reusing an already-aborted one
Example fix
// before
await uploadFile(file, { signal: controller.signal }) // throws if already aborted
// after
if (!controller.signal.aborted) {
await uploadFile(file, { signal: controller.signal })
} Defensive patterns
Strategy: try-catch
Validate before calling
function canStartUpload(signal?: AbortSignal): boolean {
return !signal?.aborted
} Type guard
function isAbortError(e: unknown): e is DOMException {
return e instanceof DOMException && e.name === 'AbortError'
} Try / catch
try {
await uploadFile(file, { signal })
} catch (e) {
if (isAbortError(e)) { markUploadCancelled(file); return } // expected cancellation
throw e
} Prevention
- Always check signal.aborted before starting an upload
- Use a dedicated AbortController per upload, not a shared/reused one
- In UI, distinguish 'cancelled' from 'failed' states
When it happens
Trigger: Calling optimizeImageForUpload (directly or via uploadFile) with an AbortSignal that was aborted before the call — e.g. user cancelled the upload, component unmounted, or a timeout fired before optimization began.
Common situations: User removes a file from an upload queue while it is pending, a React effect aborts on unmount, or an overall upload deadline aborts the controller at the optimization stage.
Related errors
- 上传已取消
- Upload canceled
- 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/8b2091d0494950e9.
Report an issue: GitHub.