Kolejka renderowania PDF
GET /documents/{id}/download renderuje PDF faktury po stronie serwera. Renderowanie obciąża procesor, więc działa w niewielkiej puli wątków roboczych z ograniczoną kolejką. Pod dużym obciążeniem kolejka może się zapełnić. Gdy tak się stanie, API nie każe Ci czekać ani nie kończy żądania timeoutem. Odpowiada natychmiast kodem 429 z kodem błędu WAIT_PDF_QUEUE, informując, że należy ponowić zapytanie za chwilę.
To co innego niż limity kwotowe. Oba zwracają 429, ale znaczą co innego:
WAIT_PDF_QUEUE |
Limit kwotowy | |
|---|---|---|
| Przyczyna | pula renderująca chwilowo wysycona | aplikacja przekroczyła swój limit na endpoint |
message |
WAIT_PDF_QUEUE |
ogólny komunikat o limicie |
| Czas trwania | sekundy (kolejka szybko schodzi) | do zresetowania okna limitu |
| Co robić | ponów po Retry-After, bez spowalniania ogólnego tempa |
wycofaj się, zwolnij, uszanuj cooldown |
Rozróżniaj po polu message (kodzie błędu), nigdy po samym statusie HTTP, aby odróżnić te dwa przypadki.
Co otrzymujesz w odpowiedzi
HTTP/1.1 429 Too Many Requests
Retry-After: 5
Content-Type: application/json
{
"success": false,
"data": null,
"message": "WAIT_PDF_QUEUE",
"executionTime": 2
}
Nagłówek Retry-After zawiera sugerowany czas oczekiwania w sekundach (zwykle 5). Uszanuj go: slot renderujący zwalnia się szybko, a ponowienie niemal zawsze kończy się sukcesem w kolejnym podejściu.
Jak to obsłużyć
Pobieranie to operacja odczytu, więc ponawianie jest zawsze bezpieczne. Nie potrzeba nagłówka Idempotency-Key. Ponawiaj, dopóki kod to WAIT_PDF_QUEUE, czekając między próbami przez czas z Retry-After:
async function downloadInvoicePdf(documentId: string, token: string): Promise<Blob> {
const url = `https://prod.api.fakturnia.pl/external/v1/documents/${documentId}/download`;
for (let attempt = 0; attempt < 10; attempt++) {
const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
if (res.ok) return res.blob();
if (res.status === 429) {
const body = await res.clone().json().catch(() => null);
// Przejściowe przeciążenie kolejki renderowania: poczekaj sugerowany czas i ponów.
if (body?.message === 'WAIT_PDF_QUEUE') {
const retryAfter = Number(res.headers.get('Retry-After')) || 5;
await new Promise(r => setTimeout(r, retryAfter * 1000));
continue;
}
}
// Każdy inny status (w tym kwotowe 429) to realny błąd tego wywołania.
throw new Error(`Pobieranie nie powiodło się: ${res.status}`);
}
throw new Error('PDF wciąż nie jest gotowy po kilku ponowieniach');
}
Pokaż oczekiwanie użytkownikowi. W aplikacji webowej i mobilnej Fakturnia przy
WAIT_PDF_QUEUEpojawia się niewielki dialog „przygotowujemy plik”, który ponawia żądanie w tle, aż PDF dotrze. Krótki, uczciwy wskaźnik postępu jest lepszy niż spinner, który wygląda na zawieszony.
Dlaczego kolejka, a nie zwykłe czekanie
Trzymanie otwartego połączenia, dopóki długi render się nie skończy, blokowałoby zasoby serwera i groziło timeoutami po stronie klienta pod obciążeniem. Ograniczona kolejka z szybką informacją zwrotną 429 utrzymuje responsywność API dla wszystkich: reszta API nie zwalnia z powodu serii pobrań w toku, a Twój klient dostaje czytelny, ponawialny sygnał zamiast nieprzejrzystego timeoutu. Zobacz Błędy, aby poznać pełną kopertę błędu, oraz Limity zapytań w sprawie zachowania kwotowego.