/**
* @module errorMiddleware
* @description Zentraler Express-Fehler-Handler der members-API.
*
* Warum ein eigenes Modul: der Handler enthielt lange nur
* `res.status(500).send('Something broke!')`. Seit dem `memberA`-Trigger
* (Migration `20260925-links-single-membera-trigger`) gibt es einen Fehler, der
* **kein** Defekt ist — die Datenbank weist eine Aenderung ab, die eine
* Invariante brechen wuerde. Solche Faelle brauchen eine eigene, testbare
* Abbildung. Als Inline-Closure in `http-server.js` war das nicht testbar.
*/
/**
* Datenbank-Signale, die eine **Invariante** durchsetzen, statt einen Defekt zu
* melden.
*
* `SIGNAL SQLSTATE '45000'` setzt bei MariaDB `errno` auf 1644
* (`ER_SIGNAL_EXCEPTION`). Die Zuordnung ist bewusst eng: nur wenn **beide**
* Werte passen, gilt es als Konflikt. Ein 1644 mit anderem SQLState waere ein
* unbekanntes Signal und soll weiter als 500 sichtbar sein, damit es nicht
* stillschweigend als "normaler Konflikt" verschwindet.
*
* @param {any} err - Fehler aus der Query-Schicht
* @returns {boolean}
*/
export const isInvariantViolation = (err) =>
err?.errno === 1644 && err?.sqlState === '45000';
/**
* Express-Fehler-Handler (4 Argumente — nur so erkennt Express ihn als solchen).
*
* @param {any} err
* @param {import('express').Request} req
* @param {import('express').Response} res
* @param {import('express').NextFunction} _next
* @returns {void}
*/
export const errorMiddleware = (err, req, res, _next) => {
if (isInvariantViolation(err)) {
// Die DB hat gerade eine Korruption verhindert — z. B. einen zweiten
// aktiven `memberA`-Link. Das ist ein Konflikt (409), kein Crash (500).
// Die Objekt-UID aus der DB-Meldung bleibt im Log; die Antwort geht an
// einen Client, der sie nicht braucht, und bleibt deshalb generisch.
console.error('Datenbank-Invariante verletzt:', err.message);
res.status(409).json({
success: false,
code: 'DB_INVARIANT_VIOLATION',
message: 'conflict: the change violates a database invariant and was rejected',
});
return;
}
console.error(err.stack);
res.status(500).send('Something broke!');
};
export default errorMiddleware;