SDK mapuje błędy HTTP i błędy walidacji na dedykowane klasy wyjątków.
| Klasa | Kiedy występuje | Najważniejsze pola |
|---|---|---|
KsefError |
Bazowy błąd SDK (np. błędy workflow). | message |
KsefHttpError |
Odpowiedź HTTP >= 400 bez JSON. | statusCode, responseBody, problem? |
KsefApiError |
Odpowiedź HTTP >= 400 z JSON. | statusCode, responseBody, problem? |
KsefRateLimitError |
429 Too Many Requests. |
statusCode, responseBody, retryAfter, retryAfterSeconds, problem? |
KsefAuthStatusError |
Specjalny przypadek 460 (status auth wskazujący m.in. zawieszony certyfikat). |
statusCode, responseBody, statusDetails |
KsefSessionExpiredError |
Brak tokena dostępowego lub nieudane odświeżenie sesji. | message |
KsefValidationError |
Błąd lokalnej walidacji danych wejściowych. | message, details |
Przy odpowiedziach JSON SDK próbuje zmapować error.problem do jednego z modeli:
BadRequestProblemDetailsdla400 application/problem+jsonUnauthorizedProblemDetailsdla401 application/problem+jsonForbiddenProblemDetailsdla403 application/problem+jsonGoneProblemDetailsdla410 application/problem+jsonTooManyRequestsProblemDetailsalbo legacyTooManyRequestsResponsedla429ExceptionResponsedla klasycznego formatu błędu KSeF- fallback
UnknownApiProblem, gdy JSON nie pasuje do znanego modelu
Mapowanie do konkretnego typed modelu następuje tylko wtedy, gdy payload spełnia wymagane pola
kontraktu ksef-docs 2.4.0. Przy częściowym albo niepoprawnym problem+json SDK zachowuje
responseBody, a error.problem przechodzi do UnknownApiProblem.
410 Gone może pojawić się po wygaśnięciu retencji technicznych statusów operacji asynchronicznych
np. dla GET /auth/{referenceNumber} albo GET /invoices/exports/{referenceNumber}.
Bogatszy format application/problem+json dla 400 i 429 jest opcjonalny i można go włączyć
przez globalny nagłówek klienta:
const client = new KsefClient({
environment: "DEMO",
headers: {
"X-Error-Format": "problem-details",
},
});import { KsefRateLimitError } from "ksef-client-typescript";
try {
await client.invoices.queryInvoiceMetadata({ subjectType: "Subject1" });
} catch (error) {
if (error instanceof KsefRateLimitError) {
console.error("Przekroczono limit. Retry-After:", error.retryAfter);
console.error("Retry-After (sekundy):", error.retryAfterSeconds);
}
throw error;
}import { KsefApiError } from "ksef-client-typescript";
try {
await client.invoices.queryInvoiceMetadata({ subjectType: "Subject1" });
} catch (error) {
if (error instanceof KsefApiError && error.problem) {
console.error(error.problem.title, error.problem.detail);
}
throw error;
}import { KsefAuthStatusError } from "ksef-client-typescript";
try {
await client.workflows.auth.authenticateWithXadesSignature({
signedXml: "<AuthTokenRequest>...signed...</AuthTokenRequest>",
});
} catch (error) {
if (error instanceof KsefAuthStatusError && error.statusCode === 460) {
console.error("Uwierzytelnianie odrzucone:", error.statusDetails);
}
throw error;
}import { KsefSessionExpiredError } from "ksef-client-typescript";
try {
await client.invoices.queryInvoiceMetadata({
subjectType: "Subject1",
dateRange: { dateType: "Issue", from: "2025-01-01", to: "2025-01-31" },
});
} catch (error) {
if (error instanceof KsefSessionExpiredError) {
console.error("Sesja wygasła. Wymagane ponowne uwierzytelnienie.");
}
throw error;
}Domyślnie biblioteka ponawia żądania tylko dla metod idempotentnych:
GETPUTDELETE
Mechanizm retry:
- respektuje nagłówek
Retry-After(sekundy lub data HTTP), - gdy nagłówek nie występuje, stosuje opóźnienie wykładnicze z jitterem,
- ogranicza opóźnienie przez
maxRetryDelayMs.
Konfiguracja globalna znajduje się w KsefClientOptions:
retryOn429maxRetryAttemptsmaxRetryDelayMs
AuthCoordinator może zgłosić KsefError, jeżeli status uwierzytelniania zakończy się kodem innym niż oczekiwany (100 w trakcie lub 200 po sukcesie), albo gdy przekroczony zostanie limit prób odpytywania.