diff --git a/library/composables/usePosterPrints.js b/library/composables/usePosterPrints.js index 515d2237c..0a9c05a11 100644 --- a/library/composables/usePosterPrints.js +++ b/library/composables/usePosterPrints.js @@ -36,6 +36,15 @@ const esc = (s) => String(s ?? '') .replace(/&/g, '&').replace(//g, '>') .replace(/"/g, '"').replace(/'/g, '''); +// A sheet the host GENERATES (opts.sheet) that fails still falls through to the stored one, so a print never comes +// out blank. It must not fall through SILENTLY: a stored sheet with an old header once printed in place of the +// generated one, and nothing said why. The console names the sheet and the reason. An empty result is not a +// failure: a generator returns '' on purpose when it cannot draw that sheet. +const generated = (draw, id, format) => Promise.resolve().then(draw).catch((e) => { + try { console.warn(`[posterPrints] the ${format} sheet for ${id} could not be generated, so the stored sheet prints instead: ${e?.message || e}`); } catch (_) { /* no console */ } + return ''; +}); + /** * THE PRINT STANDARD — one call gives any map the poster, the card deck, the prayer list and the * prayer packet (full or lightweight) for ANY item: a zone, a country, or a custom list of people. @@ -167,7 +176,7 @@ export function usePosterPrints(opts = {}) { // that cannot generate, and a generation that fails falls through to them rather than to nothing. if (opts.sheet) { set(item, kind, 'render', tr('wall.hud.generatingPoster', 'generating the poster'), 35); - const html = await Promise.resolve().then(() => opts.sheet(item, 'letter')).catch(() => ''); + const html = await generated(() => opts.sheet(item, 'letter'), id, 'letter'); if (html) { set(item, kind, 'save', tr('wall.hud.openingPrint', 'opening the print dialog'), 80); await deliver(html, item, kind); @@ -413,7 +422,7 @@ export function usePosterPrints(opts = {}) { const mapId = item && 'mapId' in item ? item.mapId : item?.id; if (!mapSvg && opts.sheet && mapId) { const target = mapId === item?.id ? item : { ...item, id: mapId }; - const html = await Promise.resolve().then(() => opts.sheet(target, 'packet')).catch(() => ''); + const html = await generated(() => opts.sheet(target, 'packet'), mapId, 'packet'); if (html) mapSvg = R.liftMap(html, { labelFor: await mapLabelFor() }); } if (!mapSvg && opts.mapImage) {