From 5ed01067846e1f5b0fb3639c3230b15208e90aa1 Mon Sep 17 00:00:00 2001 From: ht Date: Sun, 6 Sep 2026 18:57:47 +0300 Subject: [PATCH] surface retryable tender feed outages --- docs/quality/uygulama-durumu.md | 4 +++- src/services/tenderApi.js | 7 +++++-- tests/tender-api-list.test.mjs | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 tests/tender-api-list.test.mjs diff --git a/docs/quality/uygulama-durumu.md b/docs/quality/uygulama-durumu.md index 5da0624..1d8e4d4 100644 --- a/docs/quality/uygulama-durumu.md +++ b/docs/quality/uygulama-durumu.md @@ -14,7 +14,9 @@ Belge URL’si, ilan metni ve tarayıcı belge metni endpoint’leri artık 502 İhale detay istemcisi bu kodu tanıyıp “Resmi ihale kaynağı geçici olarak erişilemiyor; birkaç dakika sonra yeniden deneyin” mesajına dönüştürüyor; normal 503 gibi diğer durumlar özgün HTTP hatası olarak korunuyor. -Doğrulama: 292/292 otomatik test ve üretim derlemesi başarılı. +Ana ihale listesi istemcisi de aynı geçici kaynak mesajını kullanıyor; başarısız yanıtı boş ihale listesine çevirmiyor. + +Doğrulama: 293/293 otomatik test ve üretim derlemesi başarılı. ## Kanıtlanan ilk değişiklikler diff --git a/src/services/tenderApi.js b/src/services/tenderApi.js index 11d0d50..5c70fb3 100644 --- a/src/services/tenderApi.js +++ b/src/services/tenderApi.js @@ -6,8 +6,11 @@ export async function fetchLiveTenders({ refresh = false } = {}) { const res = await fetch(`/api/tenders${refresh ? '?refresh=1' : ''}`); - if (!res.ok) throw new Error(`API hatası: HTTP ${res.status}`); - const data = await res.json(); + const data = await res.json().catch(() => ({})); + if (!res.ok) { + if (data.code === 'SOURCE_UNAVAILABLE' && data.retryable) throw new Error('İhale kaynağı geçici olarak erişilemiyor. Birkaç dakika sonra yeniden deneyin.'); + throw new Error(`API hatası: HTTP ${res.status}`); + } if (!data.success) throw new Error(data.error || 'API başarısız yanıt döndü'); return data; } diff --git a/tests/tender-api-list.test.mjs b/tests/tender-api-list.test.mjs new file mode 100644 index 0000000..9e98e1b --- /dev/null +++ b/tests/tender-api-list.test.mjs @@ -0,0 +1,16 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { fetchLiveTenders } from '../src/services/tenderApi.js'; + +test('live tender list distinguishes retryable source outage from an empty pool', async () => { + const original = globalThis.fetch; + try { + globalThis.fetch = async url => { + assert.equal(url, '/api/tenders'); + return Response.json({ success: false, code: 'SOURCE_UNAVAILABLE', retryable: true, error: 'kaynak yok' }, { status: 502 }); + }; + await assert.rejects(() => fetchLiveTenders(), /geçici olarak erişilemiyor.*yeniden deneyin/); + globalThis.fetch = async () => Response.json({ success: true, tenders: [], totalCount: 0 }); + assert.deepEqual((await fetchLiveTenders()).tenders, []); + } finally { globalThis.fetch = original; } +});