Obsługa błędów API KSeF w aplikacji
Jak prawidłowo obsługiwać błędy zwracane przez API KSeF w Twojej aplikacji.
Przed rozpoczęciem
- Znajomość programowania (preferowany język z obsługą REST API)
- Działająca integracja z API KSeF
- Dokumentacja API KSeF
Potrzebne narzędzia
Kroki (10)
Zrozum strukturę błędów KSeF
API KSeF zwraca błędy w ustandaryzowanym formacie. Każdy błąd zawiera: - Kod błędu (np. 20001, 30002) - Komunikat opisowy - Opcjonalne szczegóły Błędy są pogrupowane według zakresu kodów: - 1xxxx - błędy autoryzacji - 2xxxx - błędy walidacji - 3xxxx - błędy biznesowe - 5xxxx - błędy serwera
// Przykładowa struktura błędu z API KSeF:
{
"exception": {
"serviceCode": "20001",
"serviceCtx": "Nieprawidłowy format NIP",
"serviceName": "SendInvoice"
}
}Zaimplementuj globalny handler błędów
Stwórz centralny mechanizm obsługi błędów, który będzie przechwytywał wszystkie odpowiedzi z API i odpowiednio je przetwarzał.
// TypeScript/JavaScript przykład:
class KsefApiError extends Error {
constructor(
public code: string,
public message: string,
public details?: unknown
) {
super(message);
this.name = 'KsefApiError';
}
isRetryable(): boolean {
// Błędy 5xxxx mogą być ponowione
return this.code.startsWith('5');
}
isAuthError(): boolean {
return this.code.startsWith('1');
}
}
async function callKsefApi(endpoint: string, data: unknown) {
const response = await fetch(endpoint, { ... });
if (!response.ok) {
const error = await response.json();
throw new KsefApiError(
error.exception.serviceCode,
error.exception.serviceCtx,
error
);
}
return response.json();
}Obsłuż błędy autoryzacji (1xxxx)
Błędy autoryzacji wymagają specjalnej obsługi - zazwyczaj oznaczają wygasły token lub brak uprawnień. Najczęstsze błędy: - 10001: Brak tokena - 10002: Token wygasł - 10003: Brak uprawnień
async function handleAuthError(error: KsefApiError) {
switch (error.code) {
case '10002': // Token wygasł
// Spróbuj odświeżyć token
await refreshToken();
// Ponów żądanie
return true;
case '10003': // Brak uprawnień
// Powiadom użytkownika o braku uprawnień
notifyUser('Brak uprawnień do wykonania tej operacji');
return false;
default:
// Wymagane ponowne logowanie
await logout();
redirectToLogin();
return false;
}
}Obsłuż błędy walidacji (2xxxx)
Błędy walidacji oznaczają problemy z danymi wejściowymi. Powinny być wyświetlane użytkownikowi w zrozumiały sposób.
const validationErrorMessages: Record<string, string> = {
'20001': 'Nieprawidłowy format NIP. Sprawdź, czy NIP zawiera 10 cyfr.',
'20002': 'Nieprawidłowy format daty. Użyj formatu YYYY-MM-DD.',
'20003': 'Brak wymaganego pola. Sprawdź czy wszystkie wymagane dane są wypełnione.',
'20004': 'Nieprawidłowa wartość. Sprawdź sumy na fakturze.',
};
function getHumanReadableError(error: KsefApiError): string {
return validationErrorMessages[error.code]
|| `Błąd walidacji: ${error.message}`;
}Zaimplementuj retry z backoff
Dla błędów serwera (5xxxx) i niektórych błędów tymczasowych, zaimplementuj mechanizm ponownych prób z wykładniczym opóźnieniem.
async function retryWithBackoff<T>(
fn: () => Promise<T>,
maxRetries = 3,
baseDelay = 1000
): Promise<T> {
let lastError: Error;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
lastError = error as Error;
if (error instanceof KsefApiError && !error.isRetryable()) {
throw error; // Nie ponawiaj błędów nienaprawialnych
}
const delay = baseDelay * Math.pow(2, attempt);
console.log(`Próba ${attempt + 1} nieudana, ponowienie za ${delay}ms`);
await sleep(delay);
}
}
throw lastError!;
}Dodaj logowanie błędów
Loguj wszystkie błędy z API w sposób umożliwiający debugowanie i analizę. Uwzględnij: - Timestamp - Kod błędu - Request ID (jeśli dostępny) - Dane żądania (bez wrażliwych informacji)
interface ErrorLog {
timestamp: string;
errorCode: string;
message: string;
requestId?: string;
endpoint: string;
duration: number;
}
function logApiError(error: KsefApiError, context: { endpoint: string; duration: number }) {
const log: ErrorLog = {
timestamp: new Date().toISOString(),
errorCode: error.code,
message: error.message,
endpoint: context.endpoint,
duration: context.duration,
};
console.error('[KSeF API Error]', JSON.stringify(log));
// Wyślij do systemu monitoringu
sendToMonitoring(log);
}Zaimplementuj circuit breaker
Dla ochrony przed kaskadowymi awariami, zaimplementuj wzorzec circuit breaker, który tymczasowo blokuje żądania gdy API jest niedostępne.
class CircuitBreaker {
private failures = 0;
private lastFailure?: Date;
private state: 'closed' | 'open' | 'half-open' = 'closed';
constructor(
private threshold = 5,
private resetTimeout = 60000
) {}
async execute<T>(fn: () => Promise<T>): Promise<T> {
if (this.state === 'open') {
if (Date.now() - this.lastFailure!.getTime() > this.resetTimeout) {
this.state = 'half-open';
} else {
throw new Error('Circuit breaker is open');
}
}
try {
const result = await fn();
this.reset();
return result;
} catch (error) {
this.recordFailure();
throw error;
}
}
private recordFailure() {
this.failures++;
this.lastFailure = new Date();
if (this.failures >= this.threshold) {
this.state = 'open';
}
}
private reset() {
this.failures = 0;
this.state = 'closed';
}
}Przetestuj obsługę błędów
Przetestuj wszystkie scenariusze błędów używając środowiska testowego KSeF. Symuluj różne typy błędów i upewnij się, że aplikacja reaguje prawidłowo.
Stwórz dashboard monitoringu
Skonfiguruj monitoring błędów aby śledzić trendy i wykrywać problemy wcześnie. Śledź: - Liczbę błędów w czasie - Najczęstsze kody błędów - Czas odpowiedzi API - Dostępność API
Udokumentuj obsługę błędów
Stwórz dokumentację dla zespołu opisującą: - Mapowanie kodów błędów na akcje - Procedury eskalacji dla krytycznych błędów - Kontakt do supportu KSeF - FAQ z najczęstszymi problemami
Ukończyłeś playbook?
Oznacz jako ukończony i podziel się opinią