====== 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