Kompletní přehled chybových stavů a hlášek REST API (oxalis-ng-rest-api)
Tento dokument shrnuje všechny HTTP chybové statusy, chybové kódy a hlášky, které aplikace může vrátit napříč filtry, interceptory, Spring Security a controllery.
1. Formát chybových odpovědí (ErrorResponseModel)
Většina chyb je serializována do jednotného JSON modelu:
{
"statusCode": 400,
"errorCode": "BAD_REQUEST",
"message": "Popis chyby...",
"timestamp": "2026-09-14 11:30:00"
}
Poznámka: V případě validačních chyb (
VALIDATION_ERROR) může být polemessagebuď textový řetězec, nebo pole objektů se strukturou:[{"id": "PEPPOL-EN16931-R001","text": "Specification identifier MUST have the value...","location": "/*:Invoice[namespace-uri()=...]","fieldName": "CustomizationID"}]
2. Chyby na úrovni Middleware, Filtrů a Spring Security
Tyto chyby vznikají ještě před zpracováním požadavku v controlleru.
| HTTP Status | errorCode | message | Zdroj / Třída | Popis / Příčina |
|---|---|---|---|---|
429 Too Many Requests | TOO_MANY_REQUESTS | "" | OverloadProtectingIntercepter + UnauthorizedRequestDenier | Databázový connection pool (HikariCP) nemá žádná volná spojení (getIdleConnections() == 0). Požadavek je ihned odmítnut. |
401 Unauthorized | UNAUTHORIZED | "" | UnauthorizedRequestDenier (Spring Security) | Požadavek na chráněný endpoint neobsahuje platný JWT token v hlavičce Authorization: Bearer <token> (token chybí, vypršel nebo je neplatný). |
403 Forbidden | (standardní Spring Security) | (standardní) | IpAuthManager | Požadavek na endpoint /api/internal/** přišel z IP adresy, která není na whitelistu (127.0.0.1, ::1, 10.20.30.0/24, 10.20.34.0/23, 185.74.61.0/24). |
3. Chyby zpracovávané přes GlobalExceptionHandler
400 Bad Request
| errorCode | Výjimka | message (chybová zpráva) | Kontext vzniku |
|---|---|---|---|
VALIDATION_ERROR | PeppolValidationException | List<ValidationErrorModel> | Selhání schematron/XSLT business pravidel Phive validátoru. |
VALIDATION_ERROR | PeppolValidationException | "Invalid type of payload" | Neplatný nebo nerozpoznaný typ dokumentu v /send_raw_validate. |
VALIDATION_ERROR | PeppolValidationException | "Failed to build Sbdh" | Selhání obalení XML do SBDH obálky. |
VALIDATION_ERROR | PeppolValidationException | "Failed to build SBD. Payload might be malformed. Cause: ..." | Chyba při tvorbě SBD obálky při odesílání faktury. |
VALIDATION_ERROR | PeppolValidationException | "Unexpected error occured while validating XML: ..." | Interní I/O nebo konfigurační chyba DOM parseru při validaci. |
XML_NOT_WELL_FORMED_ERROR | XmlParsingException | Text z ex.getCause().getMessage() | XML není syntaxně správně zformátované (neuzavřený tag, nepovolené znaky atd.). |
BAD_REQUEST | HeaderMissingException | "Missing X-PEPPOL-RECEIVER" | Chybí povinná HTTP hlavička s identifikátorem příjemce. |
BAD_REQUEST | HeaderMissingException | "Invalid X-PEPPOL-DOC-TYPE. Valid values: ..." | Neplatná hodnota hlavičky X-PEPPOL-DOC-TYPE. |
BAD_REQUEST | HeaderMissingException | "Missing headers" | Chybí povinná hlavička X-PEPPOL-DOCUMENT-ID. |
BAD_REQUEST | HeaderMissingException | "No strategy found for receiver: ..." | Nenalezena odesílací strategie pro zadaného příjemce. |
BAD_REQUEST | BadRequestException | "Bad Request" | Chybějící parametry from nebo to u filtrování v čase. |
BAD_REQUEST | BadRequestException | "Unsupported document type for flat format." | Nepodporovaný typ dokumentu pro flat formát. |
BAD_REQUEST | BadRequestException | "Start time must be before end time" | Čas od (from) je novější než čas do (to). |
BAD_REQUEST | HttpMessageNotReadableException | "" | Nečitelný nebo syntakticky chybný JSON v těle požadavku. |
BAD_REQUEST | HttpMediaTypeNotSupportedException | "" | Nepodporovaný Content-Type hlavičky. |
TYPE_MISMATCH | MethodArgumentTypeMismatchException | "Invalid parameter type: <paramName>" | Chybné datové typy v URL cestě, parametrech nebo hlavičkách (např. písmena v ID). |
SAX_PARSE_EXCEPTION | SAXParseException | ex.getMessage() | Přímá chyba SAX parseru při čtení XML. |
ERROR | ErrorException | "Error when creating send model" | Chyba při parsování Peppol hlaviček odesílatele/příjemce. |
ERROR | ErrorException | "Duplicate VAT number. Subject cannot be created" | Pokus o vytvoření subjektu s již existujícím DIČ. |
ERROR | ErrorException | "Unknown field: <key>" | Pokus o aktualizaci neznámého pole subjektu přes PATCH/PUT. |
ERROR | ErrorException | "Duplicate peppolId detected! Already belongs to Subject: ..." | Pokus o přiřazení Peppol ID, které už má jiný subjekt. |
ERROR | ErrorException | "Invalid subject update data: ..." | Porušení databázové integrity při aktualizaci subjektu. |
ERROR | ErrorException | "Subject not found" | Subjekt s daným DIČ nebyl nalezen pro aktualizaci nebo smazání. |
ERROR | ErrorException | "Subject does not exist" | Subjekt nenalezen v databázi podle ID nebo DIČ. |
ERROR | ErrorException | "Document not found" | Dokument pro zobrazení všech transakčních logů nenalezen. |
401 Unauthorized
| errorCode | Výjimka | message (chybová zpráva) | Kontext vzniku |
|---|---|---|---|
AUTHENTICATION_ERROR | AuthenticationException | "Invalid credentials" | Špatné přihlašovací jméno nebo heslo na /api/auth. |
AUTHENTICATION_ERROR | AuthenticationException | "Subject not found" | Přihlašovaný subjekt neexistuje v databázi. |
AUTHENTICATION_ERROR | AuthenticationException | "This user is not active" | Uživatel má status INACTIVE. |
AUTHENTICATION_ERROR | AuthenticationException | "Subject is inactive" | Uživatel deaktivován (při načítání v UserDetailsService). |
AUTHENTICATION_ERROR | AuthenticationException | "Document not found" | Pokus o stažení neexistujícího dokumentu na /receive nebo /receiveFlat. |
AUTHENTICATION_ERROR | AuthenticationException | "Document not yours" | Pokus o stažení dokumentu, který patří jinému subjektu. |
404 Not Found
| errorCode | Výjimka | message (chybová zpráva) | Kontext vzniku |
|---|---|---|---|
NOT_FOUND | NoResourceFoundException | "Endpoint not found" | Požadavek na neexistující URL endpoint v API. |
ERROR | ErrorException | "Subject with VAT number <vatNo> not found" | Hledání logů podle DIČ neexistujícího subjektu. |
410 Gone
| errorCode | Výjimka | message (chybová zpráva) | Kontext vzniku |
|---|---|---|---|
DOCUMENT_ERROR | DocumentException | "Document not found" | Dokument podle ID nenalezen v /api/internal/document/{id}. |
DOCUMENT_ERROR | DocumentException | "Document is already downloaded" | Dokument již byl dříve stažen (DOCSTATUS_DOWNLOADED). |
DOCUMENT_ERROR | DocumentException | "Sender of this document expects confirmation via MLS and has not accepted it yet. Please try again in few minutes." | Dokument čeká na potvrzení přes MLS (DOCSTATUS_MLSPENDING). |
DOCUMENT_ERROR | DocumentException | "This document had its body erased." | Tělo dokumentu bylo promazáno z důvodu retence (DOCSTATUS_BODY_ERASED). |
DOCUMENT_ERROR | DocumentException | "Received MLS does not correspond to any previously sent document from this Access Point" | Příchozí MLS nepotvrzuje žádný dříve odeslaný dokument. |
429 Too Many Requests
| errorCode | Výjimka | message (chybová zpráva) | Kontext vzniku |
|---|---|---|---|
SERVER_OVERLOADED | ServerOverloadedException | "Server is currently overloaded, please try again" | Aplikační limit přetížení serveru. |
500 Internal Server Error
| errorCode | Výjimka | message (chybová zpráva) | Kontext vzniku |
|---|---|---|---|
INTERNAL_ERROR | Exception.class | "Unexpected error occurred" | Obecná neošetřená výjimka (např. pád DB, NullPointerException, chyby v konfiguraci certifikátů apod.). |
ERROR | ErrorException | "Failed to create subject: ..." | Chyba persistence při vytváření nového subjektu. |
ERROR | ErrorException | "Failed to update subject: ..." | Chyba persistence při úpravě subjektu. |
ERROR | ErrorException | "Failed to delete subject: ..." | Chyba persistence při mazání (deaktivaci) subjektu. |
ERROR | ErrorException | e.getMessage() | Chyba odeslání dokumentu v /api/internal/send_raw_validate. |
502 Bad Gateway
| errorCode | Výjimka | message (chybová zpráva) | Kontext vzniku |
|---|---|---|---|
SEND_ERROR | PeppolSendException | Kořenová zpráva výjimky z Oxalis | Selhání síťového odeslání do sítě PEPPOL (např. SMP/DNS lookup selhal, remote AP timeout, TLS handshake error, odmítnutí vzdáleným AS4 přístupovým bodem). |
4. Přímé chybové odpovědi z Controllerů (neobalené v ErrorResponseModel)
Některé controllery vrací chyby přímo bez použití GlobalExceptionHandler:
-
GET /api/internal/subjects/{vatNo}:- Status:
404 Not Found - Tělo: prázdné (
ResponseEntity.notFound().build()) - Příčina: Subjekt se zadaným DIČ nebyl nalezen v databázi.
- Status:
-
POST /api/internal/send_raw:- Status:
500 Internal Server Error - Tělo: Obyčejný text s obsahem výjimky
e.toString()(ResponseEntity.internalServerError().body(...)). - Příčina: Chyba odesílání v testovacím raw endpointu.
- Status:
5. Mapování chyb podle jednotlivých Endpointů
🔑 Autentifikace (/api/auth)
POST /api/auth400 Bad Request(BAD_REQUEST): Nevalidní JSON payload nebo nepodporovaný Content-Type.401 Unauthorized(AUTHENTICATION_ERROR):"Invalid credentials","Subject not found","This user is not active".
📨 PEPPOL Veřejné API (/api/peppol)
POST /api/peppol/sendaPOST /api/peppol/sendFlat400 Bad Request(BAD_REQUEST):"Missing X-PEPPOL-RECEIVER","Invalid X-PEPPOL-DOC-TYPE...","Unsupported document type for flat format.".400 Bad Request(XML_NOT_WELL_FORMED_ERROR): XML není well-formed.400 Bad Request(VALIDATION_ERROR): Selhání Phive validace (XSLT business pravidla).401 Unauthorized(UNAUTHORIZED/AUTHENTICATION_ERROR): Chybějící/neplatný JWT token,"Subject not found".429 Too Many Requests(TOO_MANY_REQUESTS): Přetížení DB connection poolu.500 Internal Server Error(INTERNAL_ERROR): Neočekávaná systémová chyba.502 Bad Gateway(SEND_ERROR): Selhání přenosu do sítě Peppol.
GET /api/peppol/receiveaGET /api/peppol/receiveFlat400 Bad Request(BAD_REQUEST):"Missing headers"(chybíX-PEPPOL-DOCUMENT-ID).400 Bad Request(TYPE_MISMATCH): Nečíselné ID dokumentu v hlavičce.401 Unauthorized(AUTHENTICATION_ERROR):"Document not found","Document not yours".410 Gone(DOCUMENT_ERROR):"Document is already downloaded","Sender of this document expects confirmation via MLS...","This document had its body erased.".
GET /api/peppol/undownloadedaGET /api/peppol/documents400 Bad Request(TYPE_MISMATCH): Neplatný ISO formát parametrůfrom/to.401 Unauthorized(UNAUTHORIZED): Chybějící nebo neplatný JWT token.
🛡️ Interní API (/api/internal/**)
- Všechny
/api/internal/**403 Forbidden: Volající IP není na whitelistu.
GET /api/internal/document/{id}410 Gone(DOCUMENT_ERROR):"Document not found".
GET /api/internal/documents400 Bad Request(BAD_REQUEST):"Bad Request"(pokud chybí parametrfromneboto).
POST /api/internal/subjects400 Bad Request(ERROR):"Duplicate VAT number. Subject cannot be created".500 Internal Server Error(ERROR):"Failed to create subject: ...".
GET /api/internal/subjects/{vatNo}404 Not Found: prázdné tělo při neexistenci subjektu.
PUT /api/internal/subjects/{vatNo}400 Bad Request(ERROR):"Subject not found","Unknown field: ...","Duplicate peppolId detected! ...","Invalid subject update data: ...".500 Internal Server Error(ERROR):"Failed to update subject: ...".
DELETE /api/internal/subjects/{vatNo}400 Bad Request(ERROR):"Subject not found".500 Internal Server Error(ERROR):"Failed to delete subject: ...".
GET /api/internal/log/by-subject/{vatNo}404 Not Found(ERROR):"Subject with VAT number <vatNo> not found".400 Bad Request(BAD_REQUEST):"Bad Request".
GET /api/internal/log/all-transactions/{id}400 Bad Request(ERROR):"Document not found".
GET /api/internal/log/by-time-range400 Bad Request(BAD_REQUEST):"Bad Request","Start time must be before end time".