diff --git a/server/pruef-agentur.mjs b/server/pruef-agentur.mjs index 0784f804..b0ce5ed9 100644 --- a/server/pruef-agentur.mjs +++ b/server/pruef-agentur.mjs @@ -26,7 +26,7 @@ schlimmere Ausgang. ===================================================================== */ -import { mkdtempSync, rmSync, appendFileSync } from "node:fs"; +import { mkdtempSync, rmSync, appendFileSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join, dirname } from "node:path"; import { fileURLToPath } from "node:url"; @@ -61,6 +61,38 @@ const ok = (b, t) => { gemacht++; melde((b ? " ok " : " FEHL ") + t); if (!b nicht: Ein Modul wird nur einmal geladen. --------------------------------------------------------------------- */ let laufend = null; +/* DER DRITTE AUSGANG (11.09.2026). Diese Datei schreibt die + Serverausgabe immer schon mit -- und zeigte sie nur, wenn der Server + gar nicht erst hochkam. Faellt er spaeter mit 503 um (die Antwort bei + einem Datenbankfehler), standen hier 31-mal "FEHL" und kein einziges + Wort dazu, WARUM. Eine Pruefung, die nicht sagen kann, woran sie + scheitert, kostet eine Stunde Suchen. */ +let letzteAusgabe = () => ""; +/* UND SIE MUSS AUCH DANN KOMMEN, WENN DER LAUF ABSTUERZT. Playwright + wirft bei einem fehlenden Knopf eine Ausnahme -- der Prozess stirbt, + und mit ihm die Zusammenfassung samt Diagnose. Genau dann braucht + man sie am dringendsten. */ +function serverAusgabeZeigen(warum) { + const t = letzteAusgabe(); + console.log(""); + console.log(`=== Was der Server dazu gesagt hat (${warum}, letzte 1800 Zeichen) ===`); + console.log(t ? t.slice(-1800) : "(nichts -- der Server hat geschwiegen)"); + /* Und vollstaendig auf Zuruf, falls die Ursache weiter oben steht: + SERVERLOG=. Die letzten 1800 Zeichen zeigen den Schaden, + nicht immer seine Ursache. */ + if (t && process.env.SERVERLOG) { + writeFileSync(process.env.SERVERLOG, t); + console.log(`(vollstaendig in ${process.env.SERVERLOG})`); + } +} +for (const art of ["uncaughtException", "unhandledRejection"]) { + process.on(art, (e) => { + console.log(` +!! ${art}: ${e?.message || e}`); + serverAusgabeZeigen(art); + process.exit(1); + }); +} async function serverStarten() { const kind = spawn(process.execPath, [join(HIER, "index.js")], { env: { @@ -80,7 +112,11 @@ async function serverStarten() { if (kind.exitCode !== null) break; try { const a = await fetch(BASIS + "/workspace/", { redirect: "manual" }); - if (a.status < 500) { laufend = kind; return { kind, aus: () => aus }; } + if (a.status < 500) { + laufend = kind; + letzteAusgabe = () => aus; + return { kind, aus: () => aus }; + } } catch { /* noch nicht oben */ } } throw new Error("Server startete nicht:\n" + aus.slice(-1200)); @@ -709,5 +745,11 @@ await serverStoppen(); try { rmSync(ordner, { recursive: true, force: true }); } catch { /* egal */ } melde(`\n${gemacht} Pruefungen`); +if (fehler) { + const t = letzteAusgabe(); + melde(""); + melde("=== Was der Server dazu gesagt hat (letzte 1800 Zeichen) ==="); + melde(t ? t.slice(-1800) : "(nichts -- der Server hat geschwiegen)"); +} melde(fehler === 0 ? "ALLES IN ORDNUNG" : `${fehler} FEHLER`); process.exit(fehler ? 1 : 0);