→ 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 kassensichv.exceptions;
(Wird beim Import von kassensichv.manager automatisch mitgezogen.)
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 |
| 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 |
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;
}
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:
TseGetStatus()
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
}
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);
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