Files
korting/src/checkProducts.js
T
Sjoerd de Vries 358347e8ba feat: fall back to the browser scraper when the primary fetch fails
- Extract fetchAndExtractPriceViaBrowser from deps (optional)
- After primary fetch, if it errors or returns no price and fallback exists, try fallback
- Fallback result replaces primary result for further processing
- Retry-safety logic unchanged: last_price/last_checked_at only updated on success
- All 4 new tests pass, all existing tests unchanged

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013gwc3aCiyQxmCWQke8RvEz
2026-09-05 17:34:02 +02:00

60 lines
1.9 KiB
JavaScript

async function checkProduct(product, deps) {
const {
fetchAndExtractPrice, fetchAndExtractPriceViaBrowser,
sendMail, recordCheckSuccess, recordCheckFailure, now,
} = deps;
let result = await fetchAndExtractPrice(product.url);
if ((result.error || result.price == null) && fetchAndExtractPriceViaBrowser) {
result = await fetchAndExtractPriceViaBrowser(product.url);
}
if (result.error) {
console.error(`[check] fetch_error "${product.name}" (${product.url}): ${result.error.message}`);
recordCheckFailure(product.id, 'fetch_error');
return { status: 'fetch_error' };
}
if (result.price == null) {
console.error(`[check] not_found "${product.name}" (${product.url}): geen prijs gevonden op de pagina`);
recordCheckFailure(product.id, 'not_found');
return { status: 'not_found' };
}
const isBaseline = product.last_price == null;
const changed = !isBaseline && result.price !== product.last_price;
if (changed) {
try {
await sendMail({
name: product.name,
url: product.url,
oldPrice: product.last_price,
newPrice: result.price,
});
} catch (err) {
console.error(`[check] mail_error "${product.name}" (${product.url}): ${err && err.message}`);
recordCheckFailure(product.id, 'mail_error');
return { status: 'mail_error' };
}
}
recordCheckSuccess(product.id, { price: result.price, checkedAt: now() });
return { status: 'ok', changed };
}
async function checkAllProducts(products, deps) {
const results = [];
for (const product of products) {
try {
const result = await checkProduct(product, deps);
results.push({ productId: product.id, ...result });
} catch (err) {
console.error(`[check] error "${product.name}" (${product.url}): ${err && err.message}`);
results.push({ productId: product.id, status: 'error', error: err });
}
}
return results;
}
module.exports = { checkProduct, checkAllProducts };