Eine UI-Störung nennt ihren Datenbankfehler #14

Merged
claude-code merged 1 commits from failure-diagnostics into main 2026-10-23 19:26:45 +02:00
Collaborator

Der Handler protokollierte nur die Klasse der untersten Ursache. Der Schreibausfall vom 2026-10-21 stand damit als org.h2.jdbc.JdbcSQLNonTransientConnectionException im Journal und sonst nichts — eine Klasse, die bei H2 unter anderem DATABASE_IS_CLOSED (90098), OUT_OF_MEMORY (90108), FILE_CORRUPTED_1 (90030) und DATABASE_CALLED_AT_SHUTDOWN (90121) zusammenfasst, also Zustände mit völlig verschiedenen Konsequenzen für den Betrieb.

Die Zeile nennt jetzt die ganze Kette der Exception-Klassen und bei einem Datenbankfehler sqlState und errorCode des Treibers:

UI failure 7f3a21c4 (java.lang.RuntimeException <- org.jooq.exception.DataAccessException
<- org.h2.jdbc.JdbcSQLNonTransientConnectionException sqlState=90098 errorCode=90098)

Meldungen bleiben draußen. Das war der Grund der ursprünglichen Zurückhaltung und gilt unverändert: Klassennamen, SQLState und Fehlercode sind Werte des Treibers, keine Werte aus den Daten. Die Fehlerkennung, die der Nutzer sieht, bleibt unverändert die Brücke zwischen Meldung und Protokollzeile.

Dies ist das getrennt gehaltene Gegenstück zu werkjournal PR#13. Dort wurde der H2-Verbindungslebenszyklus gehärtet, die Ursache des Vorfalls aber ausdrücklich nicht belegt. Dieser Branch liefert das Mittel, sie beim nächsten Auftreten zu belegen statt zu raten.

Entscheidungen

  • Die ganze Kette, nicht nur die unterste Klasse. Die Untersuchung in PR#13 musste aus genau einer Klasse rekonstruieren, was passiert war. Dass es kein Speichermangel war — naheliegend bei -Xmx384m — ließ sich ausschließlich daran festmachen, dass unter der H2-Klasse kein java.lang.OutOfMemoryError stand. Die Kette ist also der Teil, der trennt.
  • Der letzte Datenbankfehler der Kette, nicht der erste. Spring und jOOQ hüllen den Treiberfehler in eigene SQLException-Ableitungen, deren Code und Zustand nichts aussagen.
  • Der Fehlercode zusätzlich zum SQLState. H2 2.4.240 vergibt für seine 90xxx-Fehler den Fehlercode selbst als SQLState; DATABASE_IS_CLOSED meldet sqlState=90098 statt einer 08er-Verbindungsklasse. Aus der Exception-Klasse auf eine SQLState-Klasse zu schließen, führt in die Irre — eine Annahme, die in der Untersuchung zu PR#13 widerlegt wurde.

Was an diesem Branch noch zu tun war

Der Commit lag seit dem 2026-10-21 fertig, aber unvollständig nach Projektkonvention. Ergänzt wurden: Micro-Version (0.1.127-SNAPSHOT), Nachweis unter docs/implementation/, Statuspflege im Werkbaum.

Inhaltlich korrigiert: der Kommentar im Code behauptete, die Klasse nenne „die SQLState-Klasse, aber nicht den Zustand". Für H2 2.4.240 ist das falsch — sie nennt beides nicht. Der Test führte dazu passend ein erfundenes sqlState=08003 neben errorCode=90098; er trägt jetzt die tatsächliche Form des Vorfalls (90098/90098), und ein zweiter, knapper Fall belegt mit ERROR_OPENING_DATABASE_1 (08000/8000), dass beide Felder getrennt gelesen werden.

Keine Migration, kein Schemaeingriff, keine Änderung an der Meldung für den Nutzer.

Nachweise

  • FailureDetailTest: ein Datenbankfehler in der Form des Vorfalls nennt sqlState=90098, errorCode=90098 und beide umhüllenden Klassen, und weder die SQL-Anweisung noch die darin enthaltene Adresse erscheinen in der Zeile; wo H2 Code und Zustand auseinanderhält, werden beide getrennt gelesen; eine Störung ohne Datenbankursache nennt nur ihre Klassen.
  • JAVA_HOME=~/opt/jdk25 ./tools/ci-jvm --without-firefox grün: BUILD SUCCESSFUL in 7m 12s, 72 Betriebstests.

Details: docs/implementation/failure-diagnostics.md.

Offen

Die Ursache des Vorfalls selbst. #h2-failure-proof steht im Werkbaum auf [~] und bleibt offen, bis ein tatsächlicher Vorfall mit diesen Angaben zugeordnet ist. Offen bleibt insbesondere, wieso Lesen durchgehend funktionierte, während jeder Schreibvorgang scheiterte — das passt zu keinem der eingegrenzten Kandidaten.

🤖 Generated with Claude Code

Der Handler protokollierte nur die Klasse der untersten Ursache. Der Schreibausfall vom 2026-10-21 stand damit als `org.h2.jdbc.JdbcSQLNonTransientConnectionException` im Journal und sonst nichts — eine Klasse, die bei H2 unter anderem `DATABASE_IS_CLOSED` (90098), `OUT_OF_MEMORY` (90108), `FILE_CORRUPTED_1` (90030) und `DATABASE_CALLED_AT_SHUTDOWN` (90121) zusammenfasst, also Zustände mit völlig verschiedenen Konsequenzen für den Betrieb. Die Zeile nennt jetzt die ganze Kette der Exception-Klassen und bei einem Datenbankfehler `sqlState` und `errorCode` des Treibers: UI failure 7f3a21c4 (java.lang.RuntimeException <- org.jooq.exception.DataAccessException <- org.h2.jdbc.JdbcSQLNonTransientConnectionException sqlState=90098 errorCode=90098) **Meldungen bleiben draußen.** Das war der Grund der ursprünglichen Zurückhaltung und gilt unverändert: Klassennamen, SQLState und Fehlercode sind Werte des Treibers, keine Werte aus den Daten. Die Fehlerkennung, die der Nutzer sieht, bleibt unverändert die Brücke zwischen Meldung und Protokollzeile. Dies ist das getrennt gehaltene Gegenstück zu [werkjournal PR#13](https://git.javagil.de/mi/werkjournal/pulls/13). Dort wurde der H2-Verbindungslebenszyklus gehärtet, die Ursache des Vorfalls aber ausdrücklich **nicht** belegt. Dieser Branch liefert das Mittel, sie beim nächsten Auftreten zu belegen statt zu raten. ## Entscheidungen - **Die ganze Kette, nicht nur die unterste Klasse.** Die Untersuchung in PR#13 musste aus genau einer Klasse rekonstruieren, was passiert war. Dass es kein Speichermangel war — naheliegend bei `-Xmx384m` — ließ sich ausschließlich daran festmachen, dass unter der H2-Klasse kein `java.lang.OutOfMemoryError` stand. Die Kette ist also der Teil, der trennt. - **Der letzte Datenbankfehler der Kette, nicht der erste.** Spring und jOOQ hüllen den Treiberfehler in eigene `SQLException`-Ableitungen, deren Code und Zustand nichts aussagen. - **Der Fehlercode zusätzlich zum SQLState.** H2 2.4.240 vergibt für seine 90xxx-Fehler den Fehlercode selbst als SQLState; `DATABASE_IS_CLOSED` meldet `sqlState=90098` statt einer 08er-Verbindungsklasse. Aus der Exception-Klasse auf eine SQLState-Klasse zu schließen, führt in die Irre — eine Annahme, die in der Untersuchung zu PR#13 widerlegt wurde. ## Was an diesem Branch noch zu tun war Der Commit lag seit dem 2026-10-21 fertig, aber unvollständig nach Projektkonvention. Ergänzt wurden: Micro-Version (0.1.127-SNAPSHOT), Nachweis unter `docs/implementation/`, Statuspflege im Werkbaum. Inhaltlich korrigiert: der Kommentar im Code behauptete, die Klasse nenne „die SQLState-Klasse, aber nicht den Zustand". Für H2 2.4.240 ist das falsch — sie nennt beides nicht. Der Test führte dazu passend ein erfundenes `sqlState=08003` neben `errorCode=90098`; er trägt jetzt die tatsächliche Form des Vorfalls (`90098`/`90098`), und ein zweiter, knapper Fall belegt mit `ERROR_OPENING_DATABASE_1` (`08000`/`8000`), dass beide Felder getrennt gelesen werden. Keine Migration, kein Schemaeingriff, keine Änderung an der Meldung für den Nutzer. ## Nachweise - `FailureDetailTest`: ein Datenbankfehler in der Form des Vorfalls nennt `sqlState=90098`, `errorCode=90098` und beide umhüllenden Klassen, und weder die SQL-Anweisung noch die darin enthaltene Adresse erscheinen in der Zeile; wo H2 Code und Zustand auseinanderhält, werden beide getrennt gelesen; eine Störung ohne Datenbankursache nennt nur ihre Klassen. - `JAVA_HOME=~/opt/jdk25 ./tools/ci-jvm --without-firefox` grün: `BUILD SUCCESSFUL in 7m 12s`, 72 Betriebstests. Details: `docs/implementation/failure-diagnostics.md`. ## Offen Die Ursache des Vorfalls selbst. `#h2-failure-proof` steht im Werkbaum auf `[~]` und bleibt offen, bis ein tatsächlicher Vorfall mit diesen Angaben zugeordnet ist. Offen bleibt insbesondere, wieso Lesen durchgehend funktionierte, während jeder Schreibvorgang scheiterte — das passt zu keinem der eingegrenzten Kandidaten. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
mi approved these changes 2026-10-23 19:12:03 +02:00
mi added 1 commit 2026-10-23 19:21:21 +02:00
Eine UI-Störung nennt ihren Datenbankfehler
werkator/branch build succeeded after 05:08
312a132d14
Der Handler protokollierte nur die Klasse der untersten Ursache. Der Schreibausfall vom 2026-10-21
stand damit als `org.h2.jdbc.JdbcSQLNonTransientConnectionException` im Journal und sonst nichts —
eine Klasse, die bei H2 unter anderem DATABASE_IS_CLOSED, OUT_OF_MEMORY, FILE_CORRUPTED_1 und
DATABASE_CALLED_AT_SHUTDOWN zusammenfasst, also Zustände mit völlig verschiedenen Konsequenzen.

Die Zeile nennt jetzt die ganze Kette der Exception-Klassen und bei einem Datenbankfehler
`sqlState` und `errorCode` des Treibers. Meldungen bleiben wie bisher draußen: sie können SQL-Werte
oder Nutzertext enthalten. Die Fehlerkennung bleibt die Brücke zwischen Meldung und Protokollzeile.

## Entscheidungen

- **Die ganze Kette, nicht nur die unterste Klasse.** Die Untersuchung zum
  H2-Verbindungslebenszyklus musste aus genau einer Klasse rekonstruieren, was passiert war. Dass
  es kein Speichermangel war, ließ sich nur daran festmachen, dass dort kein OutOfMemoryError
  stand — die Kette ist also der Teil, der trennt.
- **Der letzte Datenbankfehler der Kette, nicht der erste.** Spring und jOOQ hüllen den
  Treiberfehler in eigene SQLException-Ableitungen, deren Code und Zustand nichts aussagen.
- **Der Fehlercode zusätzlich zum SQLState.** H2 2.4.240 vergibt für seine 90xxx-Fehler den
  Fehlercode selbst als SQLState; DATABASE_IS_CLOSED meldet sqlState=90098 statt einer
  08er-Verbindungsklasse. Aus der Exception-Klasse auf eine SQLState-Klasse zu schließen, führt in
  die Irre.

Der Kommentar im Code behauptete bisher, die Klasse nenne „die SQLState-Klasse, aber nicht den
Zustand". Das ist für H2 2.4.240 widerlegt und entsprechend korrigiert; der Test führt jetzt die
tatsächliche Form des Vorfalls statt eines erfundenen 08003.

Keine Migration, kein Schemaeingriff, keine Änderung an der Meldung für den Nutzer.

## Nachweise

- `FailureDetailTest`: ein Datenbankfehler in der Form des Vorfalls nennt sqlState=90098,
  errorCode=90098 und beide umhüllenden Klassen, und weder die SQL-Anweisung noch die darin
  enthaltene Adresse erscheinen; wo H2 Code und Zustand auseinanderhält (08000/8000), werden beide
  getrennt gelesen; eine Störung ohne Datenbankursache nennt nur ihre Klassen.
- `JAVA_HOME=~/opt/jdk25 ./tools/ci-jvm --without-firefox` grün: BUILD SUCCESSFUL in 7m 12s,
  72 Betriebstests.

Details: `docs/implementation/failure-diagnostics.md`.

## Offen

Die Ursache des Vorfalls selbst. Der Werkbaum-Knoten `#h2-failure-proof` bleibt offen, bis ein
tatsächlicher Vorfall mit diesen Angaben zugeordnet ist. Offen bleibt insbesondere, wieso Lesen
durchgehend funktionierte, während jeder Schreibvorgang scheiterte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
mi force-pushed failure-diagnostics from eeeefae7e1 to 312a132d14 2026-10-23 19:21:22 +02:00 Compare
claude-code merged commit ff4bbe9f42 into main 2026-10-23 19:26:45 +02:00
claude-code deleted branch failure-diagnostics 2026-10-23 19:26:45 +02:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mi/werkjournal#14