fix(extractor): avoid caching results with empty meta, add some self-healing

This commit is contained in:
WebStreamr 2026-01-26 14:12:10 +00:00
parent 50a7e5559b
commit 2ba6e4fa35
No known key found for this signature in database
5 changed files with 13 additions and 11 deletions

View file

@ -32,6 +32,7 @@ export abstract class Extractor {
...urlResult,
label: this.formatLabel(urlResult.label ?? this.label),
ttl: this.ttl,
}),
);
} catch (error) {

View file

@ -49,6 +49,11 @@ describe('ExtractorRegistry', () => {
expect(urlResults).toMatchSnapshot();
});
test('empty results are cached', async () => {
const urlResults = await extractorRegistry.handle(ctx, new URL('https://dropload.io/asdfghijklmn.html'), { title: 'title' });
expect(urlResults).toMatchSnapshot();
});
test('stats returns something', async () => {
const stats = extractorRegistry.stats();

View file

@ -79,17 +79,11 @@ export class ExtractorRegistry {
this.logger.info(`Extract ${url} using ${extractor.id} extractor`, ctx);
const urlResults = await extractor.extract(
ctx,
normalizedUrl,
{
...meta,
...lazyUrlResults[0]?.meta,
extractorId: meta?.extractorId ?? extractor.id,
},
);
const mergedMeta: Meta = { ...meta, ...lazyUrlResults[0]?.meta };
const urlResults = await extractor.extract(ctx, normalizedUrl, { extractorId: extractor.id, ...mergedMeta });
if (urlResults.some(urlResult => urlResult.error)) {
if (!Object.keys(mergedMeta).length || urlResults.some(urlResult => urlResult.error)) {
await this.urlResultCache.delete(cacheKey);
await this.lazyUrlResultCache.delete(normalizedUrl.href);
return urlResults;

View file

@ -1,5 +1,7 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`ExtractorRegistry empty results are cached 1`] = `[]`;
exports[`ExtractorRegistry returns error result from extractor 1`] = `[]`;
exports[`ExtractorRegistry returns external URLs if enabled by config 1`] = `

View file

@ -54,7 +54,7 @@ export class StreamResolver {
try {
const sourceResults = await source.handle(ctx, type, id);
const sourceUrlResults = await Promise.all(
sourceResults.map(({ url, meta }) => this.extractorRegistry.handle(ctx, url, { ...meta, sourceLabel: source.label, sourceId: source.id, priority: source.priority }, true)),
sourceResults.map(({ url, meta }) => this.extractorRegistry.handle(ctx, url, { sourceLabel: source.label, sourceId: source.id, priority: source.priority, ...meta }, true)),
);
for (const urlResult of sourceUrlResults.flat()) {