mirror of
https://github.com/transloadit/uppy.git
synced 2026-07-17 16:50:22 +00:00
fix retry after setting missed metaFields (#5805)
This commit is contained in:
parent
bff36260cd
commit
eee05db260
3 changed files with 177 additions and 4 deletions
5
.changeset/rude-onions-smoke.md
Normal file
5
.changeset/rude-onions-smoke.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"@uppy/core": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix retry after setting missed metaFields requiring you to click "retry" and then "upload" again. Now "retry" immediately restarts the upload.
|
||||||
|
|
@ -1472,6 +1472,163 @@ describe('src/Core', () => {
|
||||||
await core.retryAll()
|
await core.retryAll()
|
||||||
expect(onUpload).not.toHaveBeenCalled()
|
expect(onUpload).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('with required metadata', () => {
|
||||||
|
it('should not retry files that have missing required metadata', async () => {
|
||||||
|
const onUpload = vi.fn()
|
||||||
|
const onRetryAll = vi.fn()
|
||||||
|
|
||||||
|
const core = new Core({
|
||||||
|
restrictions: {
|
||||||
|
requiredMetaFields: ['caption'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
core.on('upload', onUpload)
|
||||||
|
core.on('retry-all', onRetryAll)
|
||||||
|
|
||||||
|
const fileId = core.addFile({
|
||||||
|
source: 'vi',
|
||||||
|
name: 'foo.jpg',
|
||||||
|
type: 'image/jpeg',
|
||||||
|
data: testImage,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Simulate an upload attempt which triggers metadata validation
|
||||||
|
try {
|
||||||
|
await core.upload()
|
||||||
|
} catch (error) {
|
||||||
|
expect(error).toBeInstanceOf(RestrictionError)
|
||||||
|
expect(error.message).toContain('Missing required meta fields')
|
||||||
|
}
|
||||||
|
|
||||||
|
// File should now have missing metadata error after upload attempt
|
||||||
|
const file = core.getFile(fileId)
|
||||||
|
expect(file.missingRequiredMetaFields).toEqual(['caption'])
|
||||||
|
expect(file.error).toContain('Missing required meta fields in foo.jpg')
|
||||||
|
|
||||||
|
// Should not retry files with outstanding metadata issues
|
||||||
|
await core.retryAll()
|
||||||
|
expect(onRetryAll.mock.calls[0][0]).toEqual([])
|
||||||
|
expect(onUpload).toHaveBeenCalledTimes(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should retry files after metadata is corrected', async () => {
|
||||||
|
const onUpload = vi.fn()
|
||||||
|
const onRetryAll = vi.fn()
|
||||||
|
|
||||||
|
const core = new Core({
|
||||||
|
restrictions: {
|
||||||
|
requiredMetaFields: ['caption'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
core.on('upload', onUpload)
|
||||||
|
core.on('retry-all', onRetryAll)
|
||||||
|
|
||||||
|
const fileId = core.addFile({
|
||||||
|
source: 'vi',
|
||||||
|
name: 'foo.jpg',
|
||||||
|
type: 'image/jpeg',
|
||||||
|
data: testImage,
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
await core.upload()
|
||||||
|
} catch (error) {
|
||||||
|
expect(error).toBeInstanceOf(RestrictionError)
|
||||||
|
expect(error.message).toContain('Missing required meta fields')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify file has missing metadata error after upload attempt
|
||||||
|
const file = core.getFile(fileId)
|
||||||
|
expect(file.missingRequiredMetaFields).toEqual(['caption'])
|
||||||
|
expect(file.error).toContain('Missing required meta fields in foo.jpg')
|
||||||
|
|
||||||
|
// Fix the metadata
|
||||||
|
core.setFileMeta(fileId, { caption: 'Test caption' })
|
||||||
|
|
||||||
|
// Trigger the dashboard:file-edit-complete event to update validation state
|
||||||
|
// @ts-ignore
|
||||||
|
core.emit('dashboard:file-edit-complete', core.getFile(fileId))
|
||||||
|
|
||||||
|
const updatedFile = core.getFile(fileId)
|
||||||
|
expect(updatedFile.missingRequiredMetaFields).toEqual([])
|
||||||
|
|
||||||
|
// Now retry should work
|
||||||
|
await core.retryAll()
|
||||||
|
expect(onRetryAll.mock.calls[0][0]).toContainEqual(
|
||||||
|
expect.objectContaining({ id: fileId }),
|
||||||
|
)
|
||||||
|
expect(onUpload).toHaveBeenCalledTimes(1) // Called once during retry (initial upload failed at validation)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle multiple files with mixed metadata states', async () => {
|
||||||
|
const onUpload = vi.fn()
|
||||||
|
const onRetryAll = vi.fn()
|
||||||
|
|
||||||
|
const core = new Core({
|
||||||
|
restrictions: {
|
||||||
|
requiredMetaFields: ['caption'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
core.on('upload', onUpload)
|
||||||
|
core.on('retry-all', onRetryAll)
|
||||||
|
|
||||||
|
// Add files with missing metadata
|
||||||
|
const fileId1 = core.addFile({
|
||||||
|
source: 'vi',
|
||||||
|
name: 'file1.jpg',
|
||||||
|
type: 'image/jpeg',
|
||||||
|
data: testImage,
|
||||||
|
})
|
||||||
|
const _fileId2 = core.addFile({
|
||||||
|
source: 'vi',
|
||||||
|
name: 'file2.jpg',
|
||||||
|
type: 'image/jpeg',
|
||||||
|
data: testImage,
|
||||||
|
})
|
||||||
|
const fileId3 = core.addFile({
|
||||||
|
source: 'vi',
|
||||||
|
name: 'file3.jpg',
|
||||||
|
type: 'image/jpeg',
|
||||||
|
data: testImage,
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
await core.upload()
|
||||||
|
} catch (error) {
|
||||||
|
expect(error).toBeInstanceOf(RestrictionError)
|
||||||
|
expect(error.message).toContain('Missing required meta fields')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Give one file a different error (not metadata-related)
|
||||||
|
core.setFileState(fileId3, {
|
||||||
|
error: 'Network error',
|
||||||
|
missingRequiredMetaFields: [],
|
||||||
|
})
|
||||||
|
|
||||||
|
// Fix metadata for first file only
|
||||||
|
core.setFileMeta(fileId1, { caption: 'Fixed caption' })
|
||||||
|
// @ts-ignore
|
||||||
|
core.emit('dashboard:file-edit-complete', core.getFile(fileId1))
|
||||||
|
|
||||||
|
// Add an error to file1 so it can be retried
|
||||||
|
core.setFileState(fileId1, {
|
||||||
|
error: 'Upload failed',
|
||||||
|
})
|
||||||
|
|
||||||
|
// Retry should only include file1 and file3 (file2 still has missing metadata)
|
||||||
|
await core.retryAll()
|
||||||
|
|
||||||
|
const retriedFiles = onRetryAll.mock.calls[0][0]
|
||||||
|
expect(retriedFiles).toContainEqual(
|
||||||
|
expect.objectContaining({ id: fileId1 }),
|
||||||
|
)
|
||||||
|
expect(retriedFiles).toContainEqual(
|
||||||
|
expect.objectContaining({ id: fileId3 }),
|
||||||
|
)
|
||||||
|
expect(onUpload).toHaveBeenCalledTimes(1)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('restoring a file', () => {
|
describe('restoring a file', () => {
|
||||||
|
|
|
||||||
|
|
@ -918,13 +918,18 @@ export class Uppy<
|
||||||
this.#restricter.getMissingRequiredMetaFields(file)
|
this.#restricter.getMissingRequiredMetaFields(file)
|
||||||
|
|
||||||
if (missingFields.length > 0) {
|
if (missingFields.length > 0) {
|
||||||
this.setFileState(file.id, { missingRequiredMetaFields: missingFields })
|
this.setFileState(file.id, {
|
||||||
|
missingRequiredMetaFields: missingFields,
|
||||||
|
error: error.message,
|
||||||
|
})
|
||||||
this.log(error.message)
|
this.log(error.message)
|
||||||
this.emit('restriction-failed', file, error)
|
this.emit('restriction-failed', file, error)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (missingFields.length === 0 && file.missingRequiredMetaFields) {
|
if (missingFields.length === 0 && file.missingRequiredMetaFields) {
|
||||||
this.setFileState(file.id, { missingRequiredMetaFields: [] })
|
this.setFileState(file.id, {
|
||||||
|
missingRequiredMetaFields: [],
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -1378,8 +1383,14 @@ export class Uppy<
|
||||||
|
|
||||||
#getFilesToRetry() {
|
#getFilesToRetry() {
|
||||||
const { files } = this.getState()
|
const { files } = this.getState()
|
||||||
return Object.keys(files).filter((file) => {
|
return Object.keys(files).filter((fileId) => {
|
||||||
return files[file].error
|
const file = files[fileId]
|
||||||
|
// Only retry files that have errors AND don't have missing required metadata
|
||||||
|
return (
|
||||||
|
file.error &&
|
||||||
|
(!file.missingRequiredMetaFields ||
|
||||||
|
file.missingRequiredMetaFields.length === 0)
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue