# Application Error Logging Das Backend speichert technische Fehler zentral in `application_error_logs`. Die Tabelle ist fuer Fehleranalyse gedacht, nicht fuer fachliches Audit-Logging; bestehende Audit-Events bleiben unveraendert. ## Felder - `level`: technischer Schweregrad, aktuell `error` oder `warning`. - `category`: grobe Fehlergruppe, z. B. `EMAIL`, `EXTERNAL_API`, `DATABASE`, `BACKGROUND_JOB`, `FILE`, `UNHANDLED`. - `code`: stabiler maschinenlesbarer Fehlercode, z. B. `PASSWORD_RESET_EMAIL_SEND_FAILED`. - `message`, `stackTrace`, `errorType`: technische Fehlerdaten aus `Error`, `HttpException` oder unbekannten Fehlerwerten. - `backendModule`, `service`, `operation`: fachliche Herkunft im Backend. - `httpMethod`, `apiPath`, `httpStatusCode`: HTTP-Kontext, sofern vorhanden. - `correlationId`: Request-ID aus `X-Correlation-ID` oder eine pro Request erzeugte UUID. - `userId`, `tenantId`: Benutzer- und Mandantenkontext, sofern vorhanden. - `environment`, `host`: Laufzeitumgebung und Instanz. - `context`: bereinigte strukturierte Zusatzdaten. - `handled`: `true`, wenn der Fehler gezielt behandelt und protokolliert wurde; `false` fuer unerwartete globale Exceptions. ## Erfassung Der globale NestJS-Exception-Filter protokolliert unerwartete Exceptions und technische HTTP-Fehler ab Status 500. Erwartete fachliche Fehler wie Validierung, fehlende Berechtigungen, bewusstes 404 oder Konflikte werden nicht automatisch als Systemfehler gespeichert. Explizit protokolliert werden derzeit: - Passwort-Reset-Mailfehler mit `PASSWORD_RESET_EMAIL_SEND_FAILED`. - Registrierungs-Bestaetigungs-Mailfehler mit `REGISTRATION_VERIFICATION_EMAIL_SEND_FAILED`. - Benachrichtigung an User-Manager mit `REGISTRATION_APPROVAL_NOTIFICATION_FAILED`. - LLDAP/GraphQL- und LDAP-Integrationsfehler mit `EXTERNAL_API_REQUEST_FAILED`. Asynchrone Prozesse ohne HTTP-Request sollen den `ApplicationErrorLoggerService` direkt verwenden und `handled: true` setzen. ## Datenschutz Der Logger entfernt sensible Schluessel rekursiv und case-insensitive, darunter `password`, `currentPassword`, `newPassword`, `token`, `accessToken`, `refreshToken`, `idToken`, `authorization`, `cookie`, `secret`, `apiKey`, `clientSecret`, `resetToken` und `sessionId`. Kontextdaten werden in Tiefe, Array-Laenge, Schluesselanzahl und String-Laenge begrenzt. Zirkulaere Objekte werden sicher ersetzt. E-Mail-Adressen in freien Texten werden maskiert, z. B. `m***@example.com`. ## Fehlersuche 1. Korrelations-ID aus Response-Header `X-Correlation-ID` oder Backend-Log notieren. 2. In `application_error_logs` nach `correlationId`, `code`, `category`, `userId` oder Zeitraum suchen. 3. `handled` pruefen: `false` weist auf einen unerwarteten globalen Fehler hin, `true` auf einen gezielt behandelten technischen Fehler. 4. `context` fuer Provider-Status, maskierte Empfaenger oder Integrationsdetails verwenden. ## Beispiel ```typescript try { await this.mail.sendPasswordResetMail({ recipient: user.email, token, expiresAt: resetToken.expiresAt, }); } catch (error) { await this.applicationErrorLogger.log({ error, category: ApplicationErrorCategory.EMAIL, code: ApplicationErrorCode.PASSWORD_RESET_EMAIL_SEND_FAILED, module: 'PasswordModule', service: PasswordService.name, operation: 'sendPasswordResetEmail', requestContext: { correlationId, userId: user.id, }, context: { maskedRecipient: maskEmail(user.email), mailProvider, }, handled: true, }); throw error; } ``` ## Aufbewahrung Es gibt im Projekt derzeit keinen Scheduler oder Queue-Mechanismus. Empfohlen ist ein spaeterer, begrenzter Cleanup-Job, der Fehler aelter als 180 Tage in Batches loescht und kritische Kategorien bei Bedarf laenger aufbewahrt. Die Tabelle besitzt Indizes auf `createdAt`, `code`, `category`, `correlationId`, `userId`, `tenantId` und `httpStatusCode`.