feat: replace raw error messages with structured error codes
Backend now returns { code: ErrorCode, message: string } for all errors,
making it language-agnostic. Frontend maps codes to localised strings via
Paraglide (en/de/es), so translations live in messages/*.json.
- Add ErrorCode enum and DomainException with static factory methods
- Update GlobalExceptionHandler to return ErrorResponse(code, message)
- Replace ResponseStatusException throughout controllers/services/aspects
- Add frontend errors.ts with parseBackendError() and getErrorMessage()
- getErrorMessage() delegates to Paraglide m.error_*() functions
- Add error_* keys to messages/en.json, de.json, es.json
- Update all page.server.ts files to use the new error utilities
- Fix hardcoded localhost URLs in admin and login pages
- Fix missing baseUrl in deleteTag action
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,37 +1,24 @@
|
||||
import { error, redirect } from '@sveltejs/kit';
|
||||
import { env } from '$env/dynamic/private';
|
||||
import { parseBackendError, getErrorMessage } from '$lib/errors';
|
||||
|
||||
export async function load({ params, fetch }) {
|
||||
const { id } = params;
|
||||
|
||||
|
||||
const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
|
||||
|
||||
try {
|
||||
const res = await fetch(`${baseUrl}/api/documents/${id}`);
|
||||
|
||||
if (res.status === 404) {
|
||||
throw error(404, 'Dokument nicht gefunden');
|
||||
}
|
||||
|
||||
if (res.status === 401) {
|
||||
throw redirect(302, '/login');
|
||||
}
|
||||
if (res.status === 401) throw redirect(302, '/login');
|
||||
|
||||
if (!res.ok) {
|
||||
console.error(`Backend Fehler (${res.status}):`, res.statusText);
|
||||
throw error(500, 'Fehler beim Laden des Dokuments');
|
||||
const backendError = await parseBackendError(res);
|
||||
throw error(res.status, getErrorMessage(backendError?.code));
|
||||
}
|
||||
|
||||
const document = await res.json();
|
||||
|
||||
return {
|
||||
document
|
||||
};
|
||||
return { document: await res.json() };
|
||||
} catch (e) {
|
||||
// Fehlerbehandlung
|
||||
if (e.status) throw e; // Redirects und HttpErrors durchlassen
|
||||
console.error("Ladefehler:", e);
|
||||
throw error(500, 'Verbindung zum Server fehlgeschlagen');
|
||||
if (e.status) throw e;
|
||||
throw error(500, getErrorMessage('INTERNAL_ERROR'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +1,48 @@
|
||||
import { error, redirect } from '@sveltejs/kit';
|
||||
import { error, fail, redirect } from '@sveltejs/kit';
|
||||
import { env } from '$env/dynamic/private';
|
||||
import { parseBackendError, getErrorMessage } from '$lib/errors';
|
||||
|
||||
export async function load({ params, fetch }) {
|
||||
const { id } = params;
|
||||
|
||||
|
||||
const baseUrl = 'http://localhost:8080';
|
||||
const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
|
||||
|
||||
try {
|
||||
// Parallel Dokument und Personen laden
|
||||
const [docRes, personsRes] = await Promise.all([
|
||||
fetch(`${baseUrl}/api/documents/${id}`),
|
||||
fetch(`${baseUrl}/api/persons`)
|
||||
]);
|
||||
|
||||
if (!docRes.ok) throw error(docRes.status, 'Dokument nicht gefunden');
|
||||
if (!personsRes.ok) throw error(personsRes.status, 'Personen konnten nicht geladen werden');
|
||||
if (!docRes.ok) {
|
||||
const backendError = await parseBackendError(docRes);
|
||||
throw error(docRes.status, getErrorMessage(backendError?.code));
|
||||
}
|
||||
if (!personsRes.ok) {
|
||||
throw error(personsRes.status, getErrorMessage('INTERNAL_ERROR'));
|
||||
}
|
||||
|
||||
return {
|
||||
document: await docRes.json(),
|
||||
persons: await personsRes.json()
|
||||
};
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
throw error(500, 'Ladefehler');
|
||||
if (e.status) throw e;
|
||||
throw error(500, getErrorMessage('INTERNAL_ERROR'));
|
||||
}
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
default: async ({ request, params, fetch }) => {
|
||||
const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
|
||||
|
||||
const formData = await request.formData();
|
||||
|
||||
// Sende den FormData Request direkt an das Spring Backend weiter
|
||||
// (Spring kann Multipart verarbeiten)
|
||||
const res = await fetch(`${baseUrl}/api/documents/${params.id}`, {
|
||||
method: "PUT",
|
||||
method: 'PUT',
|
||||
body: formData
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
return { success: false, message: 'Speichern fehlgeschlagen' };
|
||||
const backendError = await parseBackendError(res);
|
||||
return fail(res.status, { error: getErrorMessage(backendError?.code) });
|
||||
}
|
||||
|
||||
throw redirect(303, `/documents/${params.id}`);
|
||||
|
||||
Reference in New Issue
Block a user