fix(downloads): don't 500 the jobs endpoint on an orphaned BullMQ job (#1191)
A job id can outlive its payload hash. BullMQ still returns an entry for it with empty `data`, so `normalize(job.data.filepath)` threw and took the whole response with it. `fetchJobsWithStates()` includes failed jobs, and failed jobs are retained deliberately, so one orphan made GET /api/downloads/jobs throw on every call, permanently. Content Explorer polls that endpoint every ~3s, so the symptom was a 500 loop and a page that never loaded. It survived restarts and only cleared by editing Redis by hand. Drop entries with no usable payload at the source, and guard both normalize() calls (the pmtiles-extract map had the same pattern). With no payload there is nothing to render anyway. Seen on NOMAD3 running rc.3: 93 occurrences in 15 minutes. Closes #1190 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
379f3def86
commit
de6f453fa7
|
|
@ -47,7 +47,12 @@ export class DownloadService {
|
|||
...active.map((j) => ({ job: j, state: 'active' as const })),
|
||||
...delayed.map((j) => ({ job: j, state: 'delayed' as const })),
|
||||
...failed.map((j) => ({ job: j, state: 'failed' as const })),
|
||||
]
|
||||
// A job id can outlive its payload hash — BullMQ still returns an entry for
|
||||
// it, with `data` empty. One of those in the failed set used to throw on
|
||||
// every poll of this endpoint (normalize(undefined)), and because failed
|
||||
// jobs are never evicted the endpoint stayed broken until Redis was cleared
|
||||
// by hand. Drop them: with no payload there is nothing to show anyway.
|
||||
].filter(({ job }) => job?.id != null && job.data != null)
|
||||
}
|
||||
|
||||
async listDownloadJobs(filetype?: string): Promise<DownloadJobWithProgress[]> {
|
||||
|
|
@ -65,7 +70,7 @@ export class DownloadService {
|
|||
jobId: job.id!.toString(),
|
||||
url: job.data.url,
|
||||
progress: parsed.percent,
|
||||
filepath: normalize(job.data.filepath),
|
||||
filepath: job.data.filepath ? normalize(job.data.filepath) : '',
|
||||
filetype: job.data.filetype,
|
||||
title: job.data.title || undefined,
|
||||
downloadedBytes: parsed.downloadedBytes,
|
||||
|
|
@ -82,7 +87,7 @@ export class DownloadService {
|
|||
jobId: job.id!.toString(),
|
||||
url: job.data.sourceUrl,
|
||||
progress: parsed.percent,
|
||||
filepath: normalize(job.data.outputFilepath),
|
||||
filepath: job.data.outputFilepath ? normalize(job.data.outputFilepath) : '',
|
||||
filetype: job.data.filetype || 'map',
|
||||
title: job.data.title || undefined,
|
||||
downloadedBytes: parsed.downloadedBytes,
|
||||
|
|
|
|||
Loading…
Reference in New Issue