koala73/worldmonitor · warning · Error

relay returned ${resp.status}

Error message

relay returned ${resp.status}

What it means

Inside the cachedFetchJson producer of searchGoogleDates, a non-OK response from the relay service (/google-flights/search-dates, 30s timeout) throws this Error. The handler's outer catch converts it into a degraded response {dates: [], degraded: true, error: 'relay returned <status>'}, so the RPC client sees HTTP 200 with degraded=true rather than a thrown error; failed fetches are not cached.

Source

Thrown at server/worldmonitor/aviation/v1/search-google-dates.ts:62

    sort_by_price: String(req.sortByPrice ?? false),
    passengers: String(passengers),
  });
  for (const airline of airlines) {
    params.append('airlines', airline);
  }

  const cacheKey = `aviation:gf-dates:${origin}:${destination}:${startDate}:${endDate}:${params.toString()}:v1`;

  try {
    const data = await cachedFetchJson<{ dates: unknown[]; partial?: boolean }>(
      cacheKey,
      CACHE_TTL,
      async () => {
        const resp = await fetch(`${relayBaseUrl}/google-flights/search-dates?${params}`, {
          headers: getRelayHeaders(),
          signal: AbortSignal.timeout(30_000),
        });
        if (!resp.ok) throw new Error(`relay returned ${resp.status}`);
        const json = (await resp.json()) as { dates?: unknown[]; partial?: boolean; error?: string };
        if (!Array.isArray(json.dates)) throw new Error(json.error ?? 'no results');
        return { dates: json.dates, partial: json.partial };
      },
    );

    if (!data) {
      return { dates: [], degraded: true, error: 'no results' };
    }

    return {
      dates: data.dates as SearchGoogleDatesResponse['dates'],
      degraded: data.partial === true,
      error: data.partial === true ? 'partial results: one or more date chunks failed' : '',
    };
  } catch (err) {
    return { dates: [], degraded: true, error: err instanceof Error ? err.message : 'search failed' };
  }

View on GitHub (pinned to 9361220cc0)

Solutions

  1. Check the response's degraded/error fields — do not treat an empty dates array as 'no flights'
  2. Verify the relay env config (base URL and shared headers via getRelayBaseUrl()/getRelayHeaders) matches the deployed relay
  3. Inspect relay service logs for the matching status code (401 → secret mismatch, 429 → throttling, 5xx → relay health)
  4. Retry after a backoff window; nothing is cached on failure so a later attempt re-hits the relay

Example fix

// before — empty array read as 'no flights on those dates'
const { dates } = await client.searchGoogleDates(req);
if (dates.length === 0) showNoFlights();

// after — degraded flag distinguishes upstream failure from a true empty result
const res = await client.searchGoogleDates(req);
if (res.degraded) showRetryableError(res.error); // 'relay returned 502'
else if (res.dates.length === 0) showNoFlights();
Defensive patterns

Strategy: fallback

Type guard

interface DatesResult { dates: unknown[]; degraded: boolean; error: string }
function isDegradedDates(r: DatesResult): boolean {
  return r.degraded === true;
}

Try / catch

// No throw escapes this handler — it converts relay failures to degraded responses.
const res = await searchGoogleDates(req);
if (res.degraded) {
  if (res.error.startsWith('relay returned')) return retryLater(res.error); // upstream status embedded
  return showEmptyState(res.error);
}

Prevention

When it happens

Trigger: Relay VM restarting or down (502/503); relay rejects the auth headers from getRelayHeaders() (401/403 — stale relay secret); relay rate-limits or blocks the request (429); Cloudflare/WAF in front of the relay rejecting the user-agent.

Common situations: Relay secret rotated but the server env (RELAY_* variables consumed by _shared/relay.ts) not updated; relay host under load during fare-search bursts; relay deployment mid-restart; network path between the Edge runtime and the relay failing.

Related errors


AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-08-21). Data as JSON: /api/errors/f261d4384c2c256a. Report an issue: GitHub.