/** * Die Fehlercodes der Partner-API und das, was ein Integrator daraufhin tun * muss. * * Das Backend antwortet auf jeden fachlichen Ausgang mit HTTP 200 und legt * seine Entscheidung in `data.code` (siehe `docs/api/partner.md` im Backend). * Der Transport hebt den Code an `KasseneckApiError.code` — hier steht, was er * bedeutet. * * **Warum die Texte hier stehen und nicht nur im Backend:** die Meldung des * Servers sagt, WAS ist. Sie sagt nicht, was der Aufrufer als naechstes tut, * und sie kann es auch nicht — dafuer muesste sie seinen Ablauf kennen. Diese * Datei ist deshalb kein zweiter Abdruck der Doku, sondern die * Handlungsanweisung daneben. * * **Der Katalog ist vollstaendig.** Die Quelle ist `docs/api/fehlercodes.json` * im Backend (Abzug aus `partner-core.FEHLER_KATALOG`); ein Code, den nur eine * Seite kennt, ist fuer einen Aufrufer nicht von „gibt es nicht" zu * unterscheiden. Deshalb stehen hier BEIDE Flaechen: die der Schnittstelle * ([PARTNER_ERROR_CODES]) und die des Partner-Portals * ([PARTNER_PORTAL_ERROR_CODES]). * * **Seit 0.29.0 englisch, wie der Rest von `/v3`.** Dieser Client spricht seit * 0.28.0 ausschliesslich `/v3` (`PARTNER_BASE_URL`): die paar deutschen Codes, * die der Server bis dahin noch roh durchreichte, kommen jetzt genauso englisch * an wie alle anderen. [PARTNER_ERROR_CODES] fuehrt deshalb ausnahmslos die * `/v3`-Schreibweise aus `fehlercodes.json`s `v3`-Zuordnung (deutsch -> englisch); * ein Aufrufer bekommt vom Server nie mehr die deutsche Form. * * **`kein_partnerbetrieb` und `request_not_found` fehlen absichtlich.** Beide * sind admin-only (`partner-endpoints.js`, ausserhalb von `FEHLER_KATALOG`) und * erreichen `/v3` nie: ein Partner-Aufruf kann sie unter keinem Pfad bekommen. * Sie standen frueher versehentlich in dieser Liste; `dart-partner.json` (ein * eingefrorener Abzug aus Dart 5.3.0, bevor das korrigiert wurde) fuehrt sie * weiterhin, siehe die Ausnahme in `test/partner-enums.test.ts`. * * **Die Vertrags-Codes (`kind_not_allowed`, `mode_not_allowed`, * `power_of_attorney_missing`, `not_found`, `no_version`, * `unknown_version`, `text_changed`, `already_accepted`)** kommen aus * `reportCustomerContract` (seit 1.0 in diesem Paket). `not_required` fehlt * bewusst: derselbe gemeinsame Server-Zweig, aber ueber die Partner-API nicht * erreichbar (der Server hat ihn aus `FEHLER_KATALOG` entfernt, siehe * `partner-core.js` im Backend). * * **Seit 1.0 ist [PARTNER_ERROR_CODES] genau `errorCodes.partner` des * Vertrags-Exports** (`fixtures/v3/v3-vokabular.json`); ein Test haelt beide * gleich. Dazu kommen die Anmelde- und Anfragecodes, die `/v3` seit * 2026-09-27 auch an Partner-Aufrufen setzt ([PARTNER_REQUEST_ERROR_CODES]). * * **Ein unbekannter Code ist kein Fehler dieses Pakets.** Der Server darf * Fehlern, die heute keinen Code tragen, spaeter einen geben (vorhandene Codes * aendern sich nie). [partnerErrorAdvice] antwortet darauf mit einem * Rueckfallsatz statt `undefined`, die Erkenner mit `false`; geworfen wird * nie. */ import { KasseneckApiError } from '../client/errors.js'; /** * Alle Codes, die die **Schnittstelle** kennt. Als Liste und nicht nur als * Typ, damit ein Aufrufer sie zur Laufzeit durchgehen kann (Katalogseite, * Selbsttest der eigenen Fehlerbehandlung). * * Reihenfolge und Bestand wie im Abzug des Backends. */ export declare const PARTNER_ERROR_CODES: readonly ["validation", "rate_limited", "app_not_found", "app_not_accepted", "live_not_allowed", "customer_exists", "customer_conflict", "customer_limit", "access_not_allowed", "email_taken", "no_email", "tax_number_missing", "fon_missing", "signature_pending", "signature_missing", "signature_unknown", "signature_ambiguous", "signature_not_ready", "signature_limit", "signature_failed", "module_inactive", "cashregister_limit", "cashregister_not_found", "contracts_pending", "kind_not_allowed", "mode_not_allowed", "power_of_attorney_missing", "not_found", "no_version", "unknown_version", "text_changed", "already_accepted", "activation_failed", "activation_in_progress", "webhook_limit", "webhook_inactive", "event_not_subscribed"]; /** * Die Codes, die nur im **Partner-Portal** entstehen — beim Pflegen der App, * der Schluessel, der Mitglieder und der Signaturkarten. * * Sie stehen hier, obwohl kein Aufruf dieses Clients sie ausloest: der * Fehlerkatalog ist eine Liste, und eine halbe Liste ist schlimmer als keine. * Wer eine Katalogseite baut oder eine fremde Antwort einsortiert, findet * damit jeden Code des Backends wieder. */ export declare const PARTNER_PORTAL_ERROR_CODES: readonly ["app_locked", "version_locked", "invalid_transition", "no_accepted_app", "consent", "key_limit", "last_owner", "auth_user_exists", "card_missing", "card_duplicate", "card_not_verified", "already_assigned"]; /** * Codes der Anmeldung und der Anfragepruefung, die `/v3` auch an * Partner-Aufrufen setzt (Partner-Doku, Abschnitt Fehlercodes; im * Vertrags-Export unter `errorCodes.auth`). Unter `/v1` kamen diese Fehler * ohne Code. `validation` und `rate_limited` stehen schon in * [PARTNER_ERROR_CODES]. Dahinter die Codes des Rands (`errorCodes.edge`, * soweit nicht schon im Katalog; `not_found` und `validation` stehen dort) * und `route_missing`, den das Paket selbst vergibt. */ export declare const PARTNER_REQUEST_ERROR_CODES: readonly ["method_not_allowed", "unauthorized", "partner_locked", "scope_missing", "internal_translation_error", "dialect_mismatch", "response_translation_failed", "route_missing"]; export type PartnerErrorCode = typeof PARTNER_ERROR_CODES[number]; export type PartnerPortalErrorCode = typeof PARTNER_PORTAL_ERROR_CODES[number]; export type PartnerRequestErrorCode = typeof PARTNER_REQUEST_ERROR_CODES[number]; /** Ein Code aus einer der Flaechen, die dieses Paket kennt. */ export type PartnerCode = PartnerErrorCode | PartnerPortalErrorCode | PartnerRequestErrorCode; /** * `true` fuer einen Code, den ein Partner-Aufruf liefern kann: aus * [PARTNER_ERROR_CODES] (Katalog) oder [PARTNER_REQUEST_ERROR_CODES] * (Anmeldung, Rand, Paket). Alles andere, auch Unsinn, ist `false`. */ export declare function isPartnerErrorCode(value: unknown): value is PartnerErrorCode | PartnerRequestErrorCode; /** `true` fuer einen Code aus [PARTNER_PORTAL_ERROR_CODES]; alles andere ist `false`. */ export declare function isPartnerPortalErrorCode(value: unknown): value is PartnerPortalErrorCode; /** * Der Handlungssatz zu einem Code, aus allen Flaechen. Fuer einen Code, den * dieses Paket nicht kennt (oder fuer Unsinn), kommt ein Rueckfallsatz; die * Funktion wirft nie. */ export declare function partnerErrorAdvice(code: string): string; /** Der Fehlercode eines geworfenen Fehlers — `undefined`, wenn es keiner der unseren ist. */ export declare function partnerErrorCode(error: unknown): string | undefined; /** * Kurzform fuer `catch (e) { if (isPartnerError(e, 'signature_missing')) … }`. * Mit `code` nimmt sie auch Codes, die dieses Paket (noch) nicht kennt. * Ohne `code`: traegt der Fehler einen Code, den ein Partner-Aufruf liefern * kann ([isPartnerErrorCode])? */ export declare function isPartnerError(error: unknown, code?: PartnerCode | (string & {})): error is KasseneckApiError; /** Ein Feldfehler aus `data.errors[]` einer `validation`-Antwort. */ export interface PartnerFieldError { /** * Der Feldpfad, so wie er im gesendeten Betrieb steht — verschachtelt und je * Kontakt: `address.zip`, `taxDetails.taxNumber`, `contacts.0.email`. */ field: string; message: string; } /** Die Feldfehler einer `validation`-Antwort; leer, wenn es keine sind. */ export declare function partnerFieldErrors(error: unknown): PartnerFieldError[]; /** * Wie lange `rate_limited` noch gilt, in Sekunden. `undefined`, wenn der * Fehler kein `rate_limited` ist oder das Backend keine Angabe macht. */ export declare function partnerRetryAfterSec(error: unknown): number | undefined;