Fix google-places losing already-fetched leads on a mid-pagination failure

search() accumulated results across up to 3 pages in a local array, but a
failure on page 2 or 3 (e.g. Google's next_page_token not active yet
despite the 2.5s wait, or a transient error) propagated out and lost the
whole accumulated array, not just the failing page. The caller's catch
only logs and continues, discarding leads that were already successfully
fetched. Now only rethrows (preserving existing behavior) when nothing has
been accumulated yet; a failure after at least one successful page logs
and returns what was already collected.

Found via a full-project audit.
This commit is contained in:
Gustavo
2026-07-31 22:16:53 -03:00
parent 3d552b5bc0
commit 3be769408c
2 changed files with 103 additions and 3 deletions
+15 -3
View File
@@ -20,14 +20,26 @@ async function searchPage(apiKey, params) {
return data;
}
async function search(query, apiKey, { maxPerQuery, pages }) {
async function search(query, apiKey, { maxPerQuery, pages }, ctx) {
const places = [];
let page = 0;
let pageToken = '';
while (page < pages && places.length < maxPerQuery) {
if (pageToken) await sleep(2500);
const data = await searchPage(apiKey, pageToken ? { pagetoken: pageToken } : { query });
let data;
try {
data = await searchPage(apiKey, pageToken ? { pagetoken: pageToken } : { query });
} catch (error) {
// Uma falha na pagina 2/3 (comum: o next_page_token do Google ainda nao
// ativou apesar da espera de 2.5s) nao pode descartar os leads ja
// trazidos pelas paginas anteriores bem-sucedidas. So propaga quando
// ainda nao ha nada acumulado (mesmo comportamento de antes: o chamador
// loga e pula a query inteira).
if (!places.length) throw error;
ctx?.log(`google-places: pagina ${page + 1} de "${query}" falhou apos ${places.length} resultado(s) ja obtidos: ${error.message}`);
break;
}
// Resultados por pagina sao no maximo 20 — spread aqui e seguro.
places.push(...(data.results || []));
page += 1;
@@ -80,7 +92,7 @@ export async function* collect(params, ctx) {
let places = [];
try {
places = await search(query, apiKey, { maxPerQuery: limits.maxPerQuery || 10, pages });
places = await search(query, apiKey, { maxPerQuery: limits.maxPerQuery || 10, pages }, ctx);
} catch (error) {
ctx.log(`google-places falhou em ${query}: ${error.message}`);
continue;