Fehler und Statuscodes
Kurzantwort: Alle CDMS-Fehler erben von AbstractCodamaiException und
tragen HTTP-Status, messageKey und die verursachende Schicht. Der zentrale
CdmsExceptionMapper (@ControllerAdvice) baut daraus eine einheitliche
JSON-Antwort und markiert den gesamten Request als rollback-only – ein
fehlgeschlagener Request committet nichts, auch nicht teilweise.
Antwortformat
Abschnitt betitelt „Antwortformat“{ "error": "ApiValidationException", "message": "validation-failed", "messageKey": "CDMS_VALIDATION_FAILED", "code": "422", "layer": "API", "violations": [ { "field": "name", "rule": "cannot-be-null" } ], "stacktrace": "…"}| Feld | Bedeutung |
|---|---|
error | einfacher Klassenname der Exception |
message | Nachricht, ggf. aus der eingebetteten Ursache |
messageKey | stabiler Schlüssel für Übersetzungen |
code | HTTP-Status als String |
layer | api, system, database, hook |
violations | nur bei Feldvalidierung: Feldpfad plus verletzte Regel |
id | nur bei CreateSucceededReadFailedException: die angelegte ID |
stacktrace | nur wenn codamai.debug = true |
Ein unerwarteter Fehler (keine CodamAI-Exception) wird als 500 mit
messageKey: "details see logfiles" beantwortet – Interna gehen ins Log, nicht
in die Antwort.
Statuscodes im Überblick
Abschnitt betitelt „Statuscodes im Überblick“| Status | Exception | Wann |
|---|---|---|
| 200 | CreateSucceededReadFailedException | Teilerfolg: Anlegen hat geklappt, Zurücklesen nicht (LENIENT); die Antwort trägt die id |
| 400 | ApiBadRequestException | fehlerhafter Request, fehlende ID im Patch |
| 400 | InvalidQueryDefinitionException | response fehlt, ungültige Abfragedefinition |
| 400 | PayloadMappingException | Payload lässt sich nicht abbilden |
| 400 | DatabaseConstraintViolationException | verletzte Datenbankbedingung, ungültige UUID |
| 400 | RecursiveOperationNotAllowed | verschachtelter Create ohne RecursiveType.CREATE (Strict Mode) |
| 403 | NoRecursiveAllowed | unerlaubte rekursive Operation |
| 403 | MissingPermissionException | Rolle fehlt (Strict Mode) |
| 404 | ApiNotFoundException | Objekt nicht gefunden |
| 404 | EntityNotFoundException | Zeile nicht vorhanden oder unter den Filtern nicht sichtbar |
| 409 | ApiConflictException | Konflikt |
| 413 | FileUploadException | Upload fehlgeschlagen, fehlende oder doppelte Dateinamen |
| 422 | ApiValidationException | Feldregeln verletzt – mit violations |
| 422 | HookValidationException | ein Hook lehnt fachlich ab |
| 422 | AttributeValidationException | Profilattribut fehlt oder ist leer |
| 500 | SystemConfigurationException | Fehlkonfiguration, unbekanntes Feld, Modell nicht auditiert |
| 500 | SystemInitializationException | Startfehler |
| 500 | HookExecutionException | Hook wirft technisch |
| 500 | DatabaseConnectionException | Verbindungsfehler |
| 500 | FileStorageException | Storage-Fehler |
| 500 | ArchiveOperationException | Archivierungsfehler |
| 500 | AuditWriteException | Revision konnte nicht geschrieben werden |
| 503 | DataIntegrityException | Integritätsproblem, z. B. beim Löschen referenzierter Daten |
Persistenz-Fehlercodes
Abschnitt betitelt „Persistenz-Fehlercodes“| Code | Status | Bedeutung |
|---|---|---|
CDMS_PERSISTENCE_CONTEXT_MISSING | 500 | kein Request-Kontext vorhanden |
CDMS_TENANT_REQUIRED | 400 | Mandantenobjekt ohne effektiven Mandanten |
CDMS_TENANT_NOT_SERVED | 403 | Mandant ist im Katalog nicht aktiv/gültig |
CDMS_TENANT_SWITCH_NOT_AUTHORIZED | 403 | Mandantenwechsel nicht erlaubt |
CDMS_TENANT_DATASOURCE_NOT_FOUND | 500 | Mandanten-Datenbank existiert nicht |
CDMS_TENANT_DATASOURCE_UNAVAILABLE | 503 | Datenbank nicht erreichbar |
CDMS_ENTITY_MANAGER_CREATION_FAILED | 500 | Persistenzkontext ließ sich nicht aufbauen |
Datei-Fehlercodes
Abschnitt betitelt „Datei-Fehlercodes“| Code | Bedeutung |
|---|---|
CDMS_FILE_STORAGE_NOT_CONFIGURED | basePath fehlt |
CDMS_FILE_CONTEXT_MISSING | mandantengebundene Operation ohne Request-Kontext |
CDMS_FILE_TENANT_REQUIRED | Kontext ohne Mandant |
CDMS_FILE_TENANT_INVALID | Mandantenkennung unzulässig (Muster [a-zA-Z0-9._-]+, kein ..) |
CDMS_FILE_SOURCE_MISSING | Quelldatei zum Speichern nicht vorhanden |
Zusätzlich als Nachrichtenschlüssel: file-not-saved, file-not-found,
file-version-not-found, could-not-delete-file.
file-storage-not-configured fällt aus der Reihe: Es meldet keinen
Speicherfehler, sondern eine fehlende Entscheidung – das System hat ein
Datei-Modell, aber storage: NONE. Siehe
Dateien und Storage.
Häufige Nachrichtenschlüssel
Abschnitt betitelt „Häufige Nachrichtenschlüssel“| Schlüssel | Situation |
|---|---|
missing-id | PATCH ohne id im data |
missing-object|<id>|<klasse> | referenziertes Objekt existiert nicht |
missing-type-for-abstract-field|<feld> | @type fehlt beim Anlegen auf einer abstrakten Beziehung |
recursive-create-not-allowed|<feld> | Beziehung erlaubt kein rekursives Anlegen |
missing-create-role / missing-update-role / missing-rollback-role | Rolle fehlt |
missing-permission|<rolle> | Klassenrolle fehlt (Strict Mode) |
missing-attribute-on-profile|<attribut> | Profilattribut fehlt |
empty-attribute-on-profile|<attribut> | Profilattribut ohne Wert |
object-already-exists|use-update | Singleton existiert bereits |
no-data-exists|use-create | Singleton existiert noch nicht |
duplicate-filenames|<namen> | doppelte Dateinamen im Upload |
model-not-audited | Historie eines nicht auditierten Modells angefragt |
Rollback-Verhalten
Abschnitt betitelt „Rollback-Verhalten“sequenceDiagram
participant C as Client
participant M as CdmsExceptionMapper
participant P as Persistenz
C->>M: Request wirft RuntimeException
M->>P: markRollbackOnly()
Note over P: gilt für ALLE berührten Ziele<br/>(System- und Mandanten-DB)
M-->>C: strukturierte Fehlerantwort
Note over P: Request-Ende rollt zurück statt zu committen
Ohne diese Markierung könnte eine Operation, die System- und
Mandantendatenbank berührt hat, das eine Ziel zurückrollen und das andere
committen. markRollbackOnly() wirft selbst nie und ist damit auch aus einem
finally sicher aufrufbar.
Feldvalidierung
Abschnitt betitelt „Feldvalidierung“Alle Verstöße eines Requests reisen in einer 422-Antwort, jeder mit vollem Feldpfad inklusive Verschachtelung. Ein Formular kann damit alle fehlerhaften Felder auf einmal markieren, statt einen pro Umlauf.
Verfügbare Regelverstöße: cannot-be-null, cannot-be-empty, too-long,
pattern-mismatch, min-number, max-number.