Hata yönetimi
listingsapi-js hata sınıflarını yakalayın, platform hata kodlarını okuyun ve retryAfter bilgisini dikkate alan yeniden deneme gecikmeleri uygulayın.
SDK'nın fırlattığı her hata ListingsAPIError sınıfından türetilir. API hataları, platform bunları ister 2xx dışında bir HTTP durum koduyla ister HTTP 200 yanıt gövdesinde bildirsin, APIError veya alt sınıflarından biri olarak fırlatılır. Ağ hataları (DNS hataları, reddedilen bağlantılar, zaman aşımları) APIConnectionError olarak fırlatılır. success bayraklarını veya ham yanıt verilerini incelemeniz gerekmez: başarıyla sonuçlanan bir promise, çağrının başarılı olduğu anlamına gelir.
Hata hiyerarşisi
ListingsAPIError base class for everything the SDK throws├── APIError any failure reported by the API│ ├── AuthenticationError 401, or invalid-token error payloads│ ├── PermissionDeniedError 403, or permission error payloads│ ├── NotFoundError 404, resource not found│ ├── ValidationError 400/422, mutations reporting success=false│ │ or errors[], and client-side payload checks│ ├── RateLimitError 429, carries retryAfter│ └── InternalServerError 5xx, retry a read; read back a write first└── APIConnectionError no response arrived: outcome unknownTüm sınıflar paketin kökünden dışa aktarılır:
import {ListingsAPIError,APIError,AuthenticationError,PermissionDeniedError,NotFoundError,ValidationError,RateLimitError,InternalServerError,APIConnectionError,} from 'listingsapi-js';APIError özellikleri
import { ListingsAPI, APIError, APIConnectionError } from 'listingsapi-js'; const client = new ListingsAPI(); try {await client.fetchAllLocations({ first: 10 });} catch (error) {if (error instanceof APIError) { console.error(error.statusCode); // 401, 429, 500, or 200 for payload errors console.error(error.code); // first platform code, e.g. 'SY10005' console.error(error.errors); // [{ code, message, context }, ...] console.error(error.responseBody); // raw body text} else if (error instanceof APIConnectionError) { // No response arrived. A read is safe to retry; for a write, read the // record back before repeating it. console.error('No response from the API:', error.message);}}Hataları türüne göre yakalama
Kimlik doğrulama hataları
import { AuthenticationError } from 'listingsapi-js'; try {await client.fetchAllLocations({ first: 1 });} catch (error) {if (error instanceof AuthenticationError) { console.error('Invalid API key. Rotate it under API Keys in the dashboard.');}}Bulunamayan kaynaklar
import { NotFoundError } from 'listingsapi-js'; try {await client.fetchPremiumListings(99999999);} catch (error) {if (error instanceof NotFoundError) { console.error('Location not found.');}}İstek hızı sınırları
RateLimitError.retryAfter, sunucunun Retry-After değerini saniye cinsinden içerir; başlık yoksa null değerini içerir:
import { RateLimitError } from 'listingsapi-js'; try {await client.fetchAllLocations({ first: 100 });} catch (error) {if (error instanceof RateLimitError) { const waitSeconds = error.retryAfter ?? 5; console.error('Rate limited, retry in ' + waitSeconds + 's');}}Doğrulama hataları
Sunucu tarafındaki doğrulama hataları, platformun hata girdilerini içerir:
import { ValidationError } from 'listingsapi-js'; try {await client.updateLocation({ id: 16808, phone: 'not-a-phone-number' });} catch (error) {if (error instanceof ValidationError) { for (const entry of error.errors) { console.error((entry.code ?? 'unknown') + ': ' + entry.message); }}}HTTP 200 yanıtlarının içindeki hatalar
Platform bazı hataları HTTP 200 durum koduyla ve gövdede hata verileriyle bildirir. SDK her yanıtı inceler ve bu durumlarda da hata fırlatır; dolayısıyla 200 durum kodu hiçbir zaman "gövdeyi kendiniz kontrol edin" anlamına gelmez:
Yazma işlemlerinde (POST ve DELETE yardımcı işlevleri), SDK yanıttaki her sonuç nesnesini kontrol eder; herhangi biri success: false bildirirse veya errors[] içerirse, statusCode değeri 200 olarak ayarlanmış bir ValidationError hatası fırlatır.
import { ValidationError } from 'listingsapi-js'; try {const result = await client.archiveLocations([16808]);console.log('Archived:', result);} catch (error) {if (error instanceof ValidationError) { // The API answered 200 but rejected the mutation console.error(error.statusCode); // 200 console.error(error.message);}}Gönderi yardımcı işlevlerinde istemci tarafı doğrulama
Gönderi yardımcı işlevleri (createAnnouncement, createEvent, createOffer ve bulkPublish), gönderecekleri verileri yerel olarak doğrular ve herhangi bir ağ çağrısından önce ValidationError fırlatır:
nameboş veya yalnızca boşluk karakterlerinden oluşan bir değer olmamalı,locationIdsise boş olmamalıdır.sites,GOOGLEveFACEBOOKdeğerlerinden oluşan kümenin boş olmayan bir alt kümesi olmalıdır.messagezorunludur; site bazında bir eşleme olduğunda, hedeflenen her site için boş olmayan ve yalnızca boşluk karakterlerinden oluşmayan bir girdi bulunmalıdır.ctaTypevectaUrlbirlikte sağlanmalıdır vectaTypeşu değerlerden biri olmalıdır:BOOK,ORDER,SHOP,LEARN_MORE,SIGN_UP,GET_OFFER.createEventvecreateOfferiçin ayrıcatitlegereklidir.bulkPublishüzerindekipostTypeşu değerlerden biri olmalıdır:ANNOUNCEMENT,EVENT,OFFER,COVID19,PRODUCT.
Bu yerel hatalar statusCode: null içerir; bu sayede bunları sunucu tarafındaki bir ret yanıtından ayırt edebilirsiniz. Düşük seviyeli createPost(body) metodu, ham gövdesini bu kontrolleri yapmadan gönderir.
import { ListingsAPI, ValidationError } from 'listingsapi-js'; const client = new ListingsAPI(); try {await client.createAnnouncement({ name: 'Grand opening', locationIds: [16808], message: 'Acme Dental is now open in Midtown!', ctaType: 'BOOK', // ctaUrl missing: throws before any request is sent});} catch (error) {if (error instanceof ValidationError && error.statusCode === null) { console.error(error.message); // Invalid post: ctaType and ctaUrl must be provided together}}Yerleşik yeniden deneme mekanizması
İstemci, 429 ve 5xx yanıtlarında (Retry-After başlığını dikkate alarak) ve ağ hatalarında varsayılan olarak 2 kez yeniden dener. Hatalar kodunuza yalnızca bu denemeler tükendikten sonra ulaşır. maxRetries ve timeout seçenekleri için Yapılandırma bölümüne bakın.
retryAfter değerini dikkate alan bir bekleyerek yeniden deneme örneği
İstemcinin yerleşik yeniden denemeleri tükendikten sonra da devam etmesi gereken uzun süreli işler için çağrıları, öncelikle sunucunun retryAfter bilgisini kullanan ve bu bilgi yoksa üstel olarak artan bekleme süreleri uygulayan bir yeniden deneme döngüsüne alın:
import {ListingsAPI,RateLimitError,InternalServerError,APIConnectionError,} from 'listingsapi-js'; const client = new ListingsAPI(); async function withBackoff<T>(fn: () => Promise<T>,maxAttempts = 5,): Promise<T> {for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { return await fn(); } catch (err) { const retryable = err instanceof RateLimitError || err instanceof InternalServerError || err instanceof APIConnectionError; if (!retryable || attempt === maxAttempts) throw err; let delayMs = 500 * 2 ** (attempt - 1); if (err instanceof RateLimitError && err.retryAfter !== null) { delayMs = err.retryAfter * 1000; } await new Promise((resolve) => setTimeout(resolve, delayMs)); }}throw new Error('unreachable');} const page = await withBackoff(() => client.fetchAllLocations({ first: 25 }));NotFoundError, ValidationError, AuthenticationError ve PermissionDeniedError durumlarında bilinçli olarak yeniden deneme yapılmaz: girdiyi veya anahtarı değiştirmeden bu istekleri tekrarlamak başarılı olamaz.
Ağ hataları ve zaman aşımları
Yanıtın ulaşmasını engelleyen her durum (DNS hatası, bağlantının reddedilmesi veya istek başına zaman aşımı süresinin dolması) APIConnectionError hatasının fırlatılmasına neden olur. SDK, fetch kaynaklı yerel TypeError veya AbortError hatalarını hiçbir zaman doğrudan dışarı aktarmaz.
APIConnectionError, isteğin sunucuya hiç ulaşmadığı anlamına gelmez. DNS hatasında veya bağlantı reddedildiğinde istek API'ye ulaşmadan durur, ancak zaman aşımı da aynı hata sınıfını kullanır ve istemci beklemeyi bıraktıktan sonra istek ulaşmış ve işlem tamamlanmış olabilir. Bunu sonucu bilinmeyen bir işlem olarak değerlendirin: okuma işlemini doğrudan yeniden deneyebilirsiniz; yazma işleminde ise API yinelenen yazma işlemlerini algılamadığından, işlemi tekrarlamadan önce kaydı yeniden okuyun.
Zaman aşımı her denemede dahili olarak AbortSignal.timeout ile uygulanır; varsayılan süre 240000 ms'dir ve timeout yapıcı seçeneğiyle yapılandırılabilir. Zaman aşımına uğrayan bir deneme, diğer bağlantı hatalarında olduğu gibi yeniden denenir; yalnızca son hata dışarıya fırlatılır:
import { ListingsAPI, APIConnectionError } from 'listingsapi-js'; const client = new ListingsAPI({ timeout: 15000 }); try {await client.fetchAllLocations({ first: 10 });} catch (error) {if (error instanceof APIConnectionError) { console.error('Network failure or timeout:', error.message);}}İlgili kaynaklar
- Yapılandırma,
timeoutvemaxRetriesseçenekleri - Hızlı başlangıç, temel hata işleme örneği
- Kullanım senaryoları, eksiksiz betiklerde gerçek kullanım koşullarına uygun hata işleme