From d7d78c0cc15f68006604ed382e93d2d5c890b2fb Mon Sep 17 00:00:00 2001 From: AI Assistant Date: Sun, 8 Mar 2026 03:06:44 +0200 Subject: [PATCH] fix(eterra-client): reduce default pageSize to 1000 + retry on ArcGIS errors - DEFAULT_PAGE_SIZE: 2000 -> 1000 (matches eTerra maxRecordCount, avoids requesting more than the server supports on first try) - PAGE_SIZE_FALLBACKS: [500, 200] (removed 1000 since it's now the default) - Add retry-once logic for 'Error performing query operation': Wait 2s and retry same page before falling to smaller sizes. These errors are often transient server-side timeouts. - Longer delay (1s vs 0.5s) between page size fallback attempts Fixes Feleacu (7951 features) background sync failure. --- .../parcel-sync/services/eterra-client.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/modules/parcel-sync/services/eterra-client.ts b/src/modules/parcel-sync/services/eterra-client.ts index 96387f4..a0d1f73 100644 --- a/src/modules/parcel-sync/services/eterra-client.ts +++ b/src/modules/parcel-sync/services/eterra-client.ts @@ -60,8 +60,8 @@ const BASE_URL = "https://eterra.ancpi.ro/eterra"; const LOGIN_URL = `${BASE_URL}/api/authentication`; const DEFAULT_TIMEOUT_MS = 40_000; -const DEFAULT_PAGE_SIZE = 2000; -const PAGE_SIZE_FALLBACKS = [1000, 500, 200]; +const DEFAULT_PAGE_SIZE = 1000; +const PAGE_SIZE_FALLBACKS = [500, 200]; const MAX_RETRIES = 2; const SESSION_TTL_MS = 9 * 60 * 1000; const MAX_URL_LENGTH = 1500; @@ -343,6 +343,7 @@ export class EterraClient { // If we request 2000 but get exactly 1000, we hit the server cap. // Track this so we continue paginating instead of stopping. let serverMaxRecordCount: number | null = null; + let retried = false; // one retry per page for transient ArcGIS errors while (true) { const params = new URLSearchParams(); @@ -360,15 +361,27 @@ export class EterraClient { data = await this.queryLayer(layer, params, Boolean(options?.geometry)); } catch (err) { const cause = err instanceof Error ? err.message : String(err); + const isQueryError = cause.includes("Error performing query"); + + // ArcGIS "Error performing query" — retry same page size first + // (often a transient server-side timeout), then try smaller. + if (isQueryError && !retried) { + retried = true; + await sleep(2000); + continue; + } + retried = false; + // Try next smaller page size const nextSize = PAGE_SIZE_FALLBACKS.find((s) => s < pageSize); if (nextSize) { pageSize = nextSize; - await sleep(500); // small delay before retry with smaller page + await sleep(1000); continue; } throw new Error(`Failed to fetch layer ${layer.name}: ${cause}`); } + retried = false; // reset on success const features = data.features ?? []; if (features.length === 0) {