kassensichv.exceptions

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:

  1. Fehler sofort in einem Fehlerprotokoll sichern (transId, Zeitstempel, Fehlermeldung)
  2. Status der TSE prüfen: TseGetStatus()
  3. Ggf. Transaktion manuell abschließen oder stornieren (Provider-abhängig)
  4. 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