fix: handle failed async downloads in upload dialog watcher

Watch the download task's status directly instead of only
lastCompletedDownload, so failed/errored tasks also transition
the dialog out of 'processing' state.
This commit is contained in:
dante01yoon
2026-04-03 19:10:38 +09:00
parent 2f194851b8
commit d73088273c
2 changed files with 65 additions and 3 deletions

View File

@@ -131,4 +131,56 @@ describe('useUploadModelWizard', () => {
// BUG: uploadStatus should be 'success' but remains 'processing'
expect(wizard.uploadStatus.value).toBe('success')
})
it('updates uploadStatus to error when async download fails', async () => {
const { assetService } =
await import('@/platform/assets/services/assetService')
const asyncResponse: AsyncUploadResponse = {
type: 'async',
task: {
task_id: 'task-fail',
status: 'created',
message: 'Download queued'
}
}
vi.mocked(assetService.uploadAssetAsync).mockResolvedValue(asyncResponse)
const wizard = useUploadModelWizard(modelTypes)
wizard.wizardData.value.url = 'https://civitai.com/models/99999'
wizard.selectedModelType.value = 'checkpoints'
await wizard.uploadModel()
expect(wizard.uploadStatus.value).toBe('processing')
// Simulate WebSocket: download fails
const { api } = await import('@/scripts/api')
const handler = vi
.mocked(api.addEventListener)
.mock.calls.find((c) => c[0] === 'asset_download')?.[1] as
| ((e: CustomEvent) => void)
| undefined
const failEvent = new CustomEvent('asset_download', {
detail: {
task_id: 'task-fail',
asset_id: '',
asset_name: 'model.safetensors',
bytes_total: 1000,
bytes_downloaded: 500,
progress: 50,
status: 'failed' as const,
error: 'Network error'
}
})
if (handler) {
handler(failEvent)
}
await nextTick()
expect(wizard.uploadStatus.value).toBe('error')
expect(wizard.uploadError.value).toBe('Network error')
})
})

View File

@@ -249,12 +249,22 @@ export function useUploadModelWizard(modelTypes: Ref<ModelTypeOption[]>) {
uploadStatus.value = 'processing'
const stopWatch = watch(
() => assetDownloadStore.lastCompletedDownload,
async (completed) => {
if (completed?.taskId === result.task.task_id) {
() =>
assetDownloadStore.downloadList.find(
(d) => d.taskId === result.task.task_id
)?.status,
async (status) => {
if (status === 'completed') {
uploadStatus.value = 'success'
await refreshModelCaches()
stopWatch()
} else if (status === 'failed') {
const download = assetDownloadStore.downloadList.find(
(d) => d.taskId === result.task.task_id
)
uploadStatus.value = 'error'
uploadError.value = download?.error || 'Download failed'
stopWatch()
}
}
)