errorMapping.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import { ApiClientError } from "@/lib/frontend/apiClient";
  2. const DEFAULT_GENERIC = Object.freeze({
  3. kind: "generic",
  4. title: "Fehler",
  5. description:
  6. "Beim Laden der Suche ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut.",
  7. });
  8. const DEFAULT_VALIDATION = Object.freeze({
  9. kind: "validation",
  10. title: "Ungültige Eingabe",
  11. description: "Bitte prüfen Sie Ihre Eingaben und versuchen Sie es erneut.",
  12. });
  13. const VALIDATION_MAP = Object.freeze({
  14. VALIDATION_SEARCH_MISSING_FILTER: {
  15. title: "Kein Suchbegriff",
  16. description: "Bitte geben Sie einen Suchbegriff ein.",
  17. },
  18. VALIDATION_SEARCH_BRANCH: {
  19. title: "Niederlassung fehlt",
  20. description: "Bitte wählen Sie eine Niederlassung aus.",
  21. },
  22. VALIDATION_SEARCH_BRANCHES: {
  23. title: "Niederlassungen fehlen",
  24. description: "Bitte wählen Sie mindestens eine Niederlassung aus.",
  25. },
  26. VALIDATION_SEARCH_SCOPE: {
  27. title: "Ungültiger Suchbereich",
  28. description: "Bitte wählen Sie einen gültigen Suchbereich aus.",
  29. },
  30. VALIDATION_SEARCH_LIMIT: {
  31. title: "Ungültige Seitengröße",
  32. description:
  33. "Die Anzahl der Ergebnisse pro Seite ist ungültig. Bitte versuchen Sie es erneut.",
  34. },
  35. VALIDATION_SEARCH_CURSOR: {
  36. title: "Ungültige Paginierung",
  37. description:
  38. "Die nächsten Ergebnisse konnten nicht geladen werden. Bitte starten Sie die Suche erneut.",
  39. },
  40. VALIDATION_SEARCH_DATE: {
  41. title: "Ungültiger Zeitraum",
  42. description: "Bitte prüfen Sie den Zeitraum und versuchen Sie es erneut.",
  43. },
  44. VALIDATION_SEARCH_RANGE: {
  45. title: "Ungültiger Zeitraum",
  46. description: "Bitte prüfen Sie den Zeitraum und versuchen Sie es erneut.",
  47. },
  48. });
  49. /**
  50. * mapSearchError
  51. *
  52. * Centralized error-to-UI mapping for Search UI (RHL-024).
  53. *
  54. * Important:
  55. * - All returned strings are user-facing => German.
  56. * - We intentionally do NOT expose raw backend messages to the UI.
  57. *
  58. * @param {unknown} err
  59. * @returns {null | {
  60. * kind: "unauthenticated"|"forbidden"|"validation"|"generic",
  61. * title: string,
  62. * description: string
  63. * }}
  64. */
  65. export function mapSearchError(err) {
  66. if (!err) return null;
  67. if (err instanceof ApiClientError) {
  68. if (err.code === "AUTH_UNAUTHENTICATED") {
  69. return {
  70. kind: "unauthenticated",
  71. title: "Sitzung abgelaufen",
  72. description:
  73. "Ihre Sitzung ist abgelaufen. Sie werden zum Login weitergeleitet.",
  74. };
  75. }
  76. if (err.code === "AUTH_FORBIDDEN_BRANCH") {
  77. return {
  78. kind: "forbidden",
  79. title: "Kein Zugriff",
  80. description:
  81. "Sie haben keine Berechtigung, diesen Suchbereich zu verwenden.",
  82. };
  83. }
  84. if (String(err.code || "").startsWith("VALIDATION_")) {
  85. const mapped = VALIDATION_MAP[err.code];
  86. return {
  87. kind: "validation",
  88. title: mapped?.title || DEFAULT_VALIDATION.title,
  89. description: mapped?.description || DEFAULT_VALIDATION.description,
  90. };
  91. }
  92. if (err.code === "CLIENT_NETWORK_ERROR") {
  93. return {
  94. kind: "generic",
  95. title: "Netzwerkfehler",
  96. description:
  97. "Bitte prüfen Sie Ihre Verbindung und versuchen Sie es erneut.",
  98. };
  99. }
  100. return DEFAULT_GENERIC;
  101. }
  102. return DEFAULT_GENERIC;
  103. }