Fix #772: manual import progress bar stuck at 0 / 'Failed' on slow imports
Per-track import does heavy synchronous server-side enrichment (metadata, art, lyrics) that can take 60-90s/track, far longer when external sources are degraded. The React apiClient (ky) had no timeout, so ky's default 10s aborted the import-process request client-side even though the server completed the import (200) and moved the files. The import loop then counted the aborted call as an error, so the bar stayed at 0 and flipped to 'Failed' while files imported fine. Give the two import-process calls (album/process, singles/process) an explicit 5-min timeout. Scoped to import only -- every other endpoint keeps the 10s default; bounded, not disabled. Server behavior unchanged. Adds a test asserting both calls pass the long timeout.
This commit is contained in:
parent
e27e436465
commit
7956aaac9e
2 changed files with 36 additions and 2 deletions
|
|
@ -1,8 +1,14 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { apiClient } from '@/app/api-client';
|
||||
import { HttpResponse, http, server } from '@/test/msw';
|
||||
|
||||
import { approveAutoImportResult, rejectAutoImportResult } from './-import.api';
|
||||
import {
|
||||
approveAutoImportResult,
|
||||
processImportAlbumTrack,
|
||||
processImportSingleFile,
|
||||
rejectAutoImportResult,
|
||||
} from './-import.api';
|
||||
|
||||
const softFailureMessage = 'Item not found or not pending review';
|
||||
|
||||
|
|
@ -26,4 +32,21 @@ describe('import api', () => {
|
|||
await expect(approveAutoImportResult(17)).rejects.toThrow(softFailureMessage);
|
||||
await expect(rejectAutoImportResult(18)).rejects.toThrow(softFailureMessage);
|
||||
});
|
||||
|
||||
it('#772: import-process calls use a long timeout, not ky default 10s', async () => {
|
||||
// Per-track import does heavy server-side enrichment (60-90s+); the default
|
||||
// 10s timeout aborted it client-side -> progress bar stuck + "Failed" while
|
||||
// files imported. These calls must pass an explicit long timeout.
|
||||
const ok = { json: async () => ({ success: true, processed: 1, total: 1, errors: [] }) };
|
||||
const spy = vi.spyOn(apiClient, 'post').mockReturnValue(ok as never);
|
||||
|
||||
await processImportAlbumTrack({ album: {} as never, match: {} as never });
|
||||
await processImportSingleFile({});
|
||||
|
||||
expect(spy).toHaveBeenCalledTimes(2);
|
||||
for (const call of spy.mock.calls) {
|
||||
expect(call[1]).toMatchObject({ timeout: 300_000 });
|
||||
}
|
||||
spy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -18,6 +18,15 @@ import type {
|
|||
|
||||
export const IMPORT_QUERY_KEY = ['import'] as const;
|
||||
|
||||
// Per-track import does heavy synchronous enrichment server-side (metadata
|
||||
// lookups, art, lyrics) and can legitimately take 60-90s/track — much longer
|
||||
// when external sources are degraded. ky's default 10s timeout aborts those
|
||||
// requests client-side even though the server completes the import (200),
|
||||
// which left the progress bar stuck at 0 and showing "Failed" while files
|
||||
// imported fine (#772). Give the import-process calls a generous bound so the
|
||||
// responses actually arrive and the bar advances. Scoped to import only.
|
||||
const IMPORT_REQUEST_TIMEOUT_MS = 300_000; // 5 min/track
|
||||
|
||||
export async function fetchImportStagingFiles(): Promise<ImportStagingFilesPayload> {
|
||||
return readJson<ImportStagingFilesPayload>(apiClient.get('import/staging/files'));
|
||||
}
|
||||
|
|
@ -71,6 +80,7 @@ export async function processImportAlbumTrack(input: {
|
|||
album: input.album,
|
||||
matches: [input.match],
|
||||
},
|
||||
timeout: IMPORT_REQUEST_TIMEOUT_MS,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
@ -92,6 +102,7 @@ export async function processImportSingleFile(file: unknown): Promise<ImportProc
|
|||
json: {
|
||||
files: [file],
|
||||
},
|
||||
timeout: IMPORT_REQUEST_TIMEOUT_MS,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue