CodamAIDocs
Themafertig

Wenn ein Hook scheitert

Ein Fehler im Hook rollt den ganzen Request zurück. Wie der Fehler beim Client ankommt.

Ausprägungen
Before-Hook wirftAfter-Hook wirftREAD-Hook wirftHookValidationException → 422HookExecutionException → 500andere Exception → 500

Worum es geht

Ein Hook meldet einen Fehler, indem er eine Exception wirft. Eine Exception ist in Java ein Objekt, das den normalen Ablauf abbricht und nach oben weitergereicht wird, bis jemand es behandelt. In CDMS behandelt es die zentrale Fehlerbehandlung: Sie rollt die Anfrage zurück und baut die Fehlerantwort.

Ein Hook scheitert also nie allein. Er nimmt die ganze Anfrage mit: das Objekt, alle Kinder, alle mitgelöschten Objekte, alles, was andere Hooks vorher in der Datenbank geändert haben.

Welche Exception welche Antwort gibt

Dein Hook wirftStatuserrormessageKeylayer
HookValidationException("stock-negative", null)422HookValidationExceptionstock-negativehook
HookExecutionException("erp-unreachable", e)500HookExecutionExceptionerp-unreachablehook
eine andere CodamAI-Exception, etwa NoAccessExceptionderen Statusderen Klassederen Schlüsselderen Schicht
jede andere Exception, etwa IllegalStateException500Name einer Java-Klassedetails see logfilesundefined

Beide Hook-Exceptions liegen in com.codamai.cdms.commons.exceptions. Der erste Parameter ist der Schlüssel, den der Client auswertet. Der zweite ist eine optionale Ursache: Gibst du eine mit, steht ihr Text in message.

Ein Before-Hook lehnt ab
Anfrage
PATCH /api/rest/shop/stock/update/s-17
{ "data": { "id": "s-17", "quantity": -3 }, "response": ["id", "quantity"] }
Antwort 422
{
  "error": "HookValidationException",
  "messageKey": "stock-negative",
  "code": "422",
  "layer": "hook"
}

Eine Antwort aus einem Hook hat keine violations. Den Text für den Benutzer baust du im Client aus messageKey. Wie das Fehlerformat allgemein aussieht, steht unter Das Fehlerformat.

Before, After, READ

Wo der Hook scheitert

Wann: in beforeDatabaseChange, bei Create, PUT, PATCH, DELETE oder ROLLBACK

  1. 1
    CDMS
    Rekursion fertig, Rollen geprüft
  2. 2
    Hook
    wirft eine Exception
  3. 3
    CDMS
    bricht sofort ab: keine weiteren Before-Hooks, keine Validierung, kein Speichern, keine After-Hooks
  4. 4
    CDMS→Database
    rollt die Anfrage zurück
  5. 5
    CDMS→Client
    Fehlerantwort, z. B. 422 stock-negative

Ergebnis: Nichts ist gespeichert. Auch gesammelte Validierungsverstöße kommen nicht mehr in die Antwort, denn die Validierung urteilt erst nach den Before-Hooks.

Wann: in afterDatabaseChange, bei Create, PUT, PATCH, DELETE oder ROLLBACK

  1. 1
    CDMS→Database
    hat das Objekt schon übergeben, aber noch nicht festgeschrieben
  2. 2
    Hook
    wirft eine Exception
  3. 3
    CDMS
    bricht ab: keine weiteren After-Hooks, kein flush, kein Zurücklesen
  4. 4
    CDMS→Database
    rollt die Anfrage zurück
  5. 5
    CDMS→Client
    Fehlerantwort

Ergebnis: Nichts ist gespeichert, obwohl die Before-Hooks und die Validierung durchgelaufen sind. After-Hooks laufen vor dem Commit.

Wann: in afterDatabaseChange mit READ, beim Lesen, Suchen oder Zurücklesen

  1. 1
    Hook
    wirft beim Lesen eine Exception
  2. 2
    CDMS→Client
    beim reinen Lesen oder Suchen: Fehlerantwort statt Daten
  3. 3
    CDMS→Database
    beim Zurücklesen nach PUT, PATCH, ROLLBACK und Create im Modus STRICT: rollt die Änderung zurück

Ergebnis: Beim Create im Modus LENIENT bleibt das Objekt angelegt. Siehe Anlegen und Zurücklesen: STRICT oder LENIENT.

Wie weit das Zurückrollen reicht

Ein Hook eines Kindes wirft
  1. 1
    Client→CDMS
    PUT /department/update/d-1 mit zwei geänderten und einem neuen Mitarbeiter
  2. 2
    Hook
    die Before-Hooks der ersten Objekte laufen durch
  3. 3
    Hook
    der Before-Hook eines Mitarbeiters wirft HookValidationException
  4. 4
    CDMS→Database
    rollt die ganze Anfrage zurück: die Abteilung, alle drei Mitarbeiter, auch mitgelöschte Kinder
  5. 5
    CDMS→Client
    422 mit dem Schlüssel aus dem Hook
    Ergebnis: Die Datenbank sieht aus wie vor der Anfrage.

Es gibt keinen Teil-Erfolg. Egal, auf welcher Stufe des Baums der Hook sitzt: Die Anfrage ist eine Transaktion. Siehe Ein Request, eine Transaktion.

Entscheidungstabelle

Was bleibt, wenn ein Hook wirft
Wo der Hook wirftOperationErgebnis
beforeCreate, PUT, PATCH, DELETE, ROLLBACKFehlerantwort, nichts gespeichert
afterCreate, PUT, PATCH, DELETE, ROLLBACKFehlerantwort, nichts gespeichert
READLesen, SuchenFehlerantwort, keine Daten
READZurücklesen nach PUT, PATCH, ROLLBACK oder Create mit STRICTFehlerantwort, nichts gespeichert
READZurücklesen nach Create mit LENIENTObjekt angelegt, Antwort mit der id statt des Objekts

Fallen

Wie es weitergeht

Quellen im Code und in der Wissensdatenbank
  • commons – global/commons/exceptions/AbstractCodamaiException (httpStatusCode, messageKey, layer, embedded)
  • CDMS/cdms-commons – exceptions/HookValidationException (422, layer hook), HookExecutionException (500, layer hook)
  • CDMS/cdms-system-layer – AbstractSystemLayer, AbstractSystemSingletonLayer (createObject, updateObject, patchObject, deleteObject, historyRollback, readObject: rollback, throw); session/HookRequestContext (runBefore, runAfter)
  • CDMS/cdms-rest-api – CdmsExceptionMapper (markRollbackOnly, handleCmsException, handleDefault), RequestTransactionCommitter
  • documentation/60-erweiterung/01-hooks.md
Suchen