====== kassensichv.exceptions ====== → [[lyx_-_programmiersprache:units:kassensichv|Zurück zur KassenSichV-Übersicht]] Strukturierte Fehler-Hierarchie der KassenSichV-Bibliothek. Alle TSE-spezifischen Fehler werden einheitlich als ''TseError''-Struktur zurückgegeben — kein Fehlertyp aus internen Implementierungen dringt nach außen. ===== Import ===== import kassensichv.exceptions; (Wird beim Import von ''kassensichv.manager'' automatisch mitgezogen.) ===== TseError-Struktur ===== pub type TseError = struct { code: int64; // HTTP-analoger Fehlercode message: int64; // pchar — deutschsprachige Fehlermeldung provider: int64; // pchar — Name des auslösenden Providers } ^ Feld ^ Typ ^ Beschreibung ^ | ''code'' | ''int64'' | HTTP-analoger Code (400/403/408/409/500/503) | | ''message'' | ''int64'' (pchar) | Deutschsprachige Fehlermeldung mit Kontext | | ''provider'' | ''int64'' (pchar) | Name des Providers: ''MockTseProvider'', ''RestTseProvider'', ''FileTseProvider'' | ===== Fehlercodes ===== ^ Code ^ Bedeutung ^ Typische Ursachen ^ | **400** | Konfigurationsfehler | Pflichtfeld fehlt in ConfigJSON, ungültiges JSON | | **403** | Exportfehler | Exportpfad existiert nicht oder nicht schreibbar | | **408** | Timeout | USB-TSE antwortet nicht innerhalb ''timeout_ms''; Cloud nicht erreichbar | | **409** | Transaktionsfehler | Offene Transaktion, ungültige TransId, doppelte TransId | | **500** | Signierfehler | ECDSA-Schlüssel ungültig, TSE-interne Fehler | | **503** | Verbindungsfehler | USB-TSE nicht verbunden, Cloud-API nicht erreichbar, HTTP 503/504 nach 3 Retries | ===== Fehlerbehandlung in der Praxis ===== Funktionen des ''TseManager'' geben Fehler über das ''success''-Feld in ''SigErgebnis'' zurück: import kassensichv.types; import kassensichv.rest; import kassensichv.manager; fn BelegMitFehlerbehandlung(mgr: int64, beleg: int64): int64 { var sig: int64 := TseProcessBeleg(mgr, beleg); if sig == 0 then { return 0; // Manager-Fehler (nullptr) } var s: SigErgebnis := (sig as *SigErgebnis)^; if s.success == 0 then { Print("TSE-Fehler: "c); PrintLn(s.errorMsg as pchar); // Fehlercode für differenzierte Behandlung (in zukünftiger API) SigErgebnisFree(sig); return 0; } // Pflichtdaten drucken PrintLn(s.qrCode as pchar); SigErgebnisFree(sig); return 1; } ===== Offene Transaktionen — Compliance-Problem ===== Wenn ''TseCloseBeleg'' mit ''success=0'' zurückkommt, hat die TSE die Transaktion möglicherweise **nicht abgeschlossen**. Eine offen gebliebene TSE-Transaktion ist eine **Ordnungswidrigkeit** für den Kassenbetreiber. **Pflichtverhalten der Kassensoftware:** - Fehler sofort in einem Fehlerprotokoll sichern (transId, Zeitstempel, Fehlermeldung) - Status der TSE prüfen: ''TseGetStatus()'' - Ggf. Transaktion manuell abschließen oder stornieren (Provider-abhängig) - Bondruckvorgang erst freigeben, wenn die Transaktion abgeschlossen ist var sig: int64 := TseCloseBeleg(mgr, transId, addr beleg); var s: SigErgebnis := (sig as *SigErgebnis)^; if s.success == 0 then { // COMPLIANCE: Offene Transaktion loggen! Print("[COMPLIANCE-WARNUNG] Offene TSE-Transaktion: "c); PrintLn(transId as pchar); Print("Fehler: "c); PrintLn(s.errorMsg as pchar); // Status der TSE prüfen var status: int64 := TseGetStatus(mgr); Print("TSE-Status: "c); PrintLn(status as pchar); free(status); SigErgebnisFree(sig); return 0; // Bon NICHT drucken bis Situation geklärt } ===== Konfigurationsfehler früh erkennen ===== Bei ''TseRestNew'' / ''TseFileNew'' mit fehlendem Pflichtfeld in der JSON-Konfiguration liefert der erste ''TseProcessBeleg''-Aufruf ''success=0'' mit code=400. Besser: Konfiguration beim Programmstart prüfen, nicht erst beim ersten Bon: var mgr: int64 := TseRestNew(cfg as int64); var status: int64 := TseGetStatus(mgr); var st: pchar := status as pchar; // Status-JSON enthält "status":"error" bei Konfigurationsproblem if ... then { PrintLn("TSE-Konfiguration ungültig — Programmstart abgebrochen"c); free(status); TseManagerFree(mgr); return 1; } free(status); ===== Log-Hinweis ===== Alle Provider loggen über einen optionalen Callback. Der API-Key des REST-Providers erscheint **niemals** im Klartext in Logs — nur die ersten 4 Zeichen gefolgt von ''***''. Das entspricht der KassenSichV-Anforderung, Zugangsdaten zu schützen. ----- Letzte Aktualisierung: 2026-06-12