Initial microservice-importer setup with NestJS backend and Next.js frontend

This commit is contained in:
Nils-Johan Gynther
2026-04-12 16:58:23 +02:00
commit 1608eb4d70
32 changed files with 1619 additions and 0 deletions
+27
View File
@@ -0,0 +1,27 @@
const API_BASE =
process.env.NEXT_PUBLIC_API_URL_INTERNAL || 'http://localhost:3001';
export async function fetchJson<T>(path: string, init?: RequestInit): Promise<T> {
// Använd alltid relativ path i webbläsaren för att undvika mixed content
const url = typeof window === 'undefined'
? (path.startsWith('http') ? path : `${API_BASE}${path}`)
: path;
const res = await fetch(url, {
...init,
cache: 'no-store',
headers: {
'Content-Type': 'application/json',
...(init?.headers || {}),
},
});
if (!res.ok) {
const text = await res.text();
throw new Error(`API ${res.status}: ${text}`);
}
return res.json();
}
export { API_BASE };
+45
View File
@@ -0,0 +1,45 @@
/**
* Utility för att parse HTTP-responses och extrahera tydliga felmeddelanden
*/
export async function parseErrorResponse(response: Response): Promise<string> {
const status = response.status;
try {
const data = await response.json();
// Om backend skickade ett felmeddelande
if (data.message) {
return data.message;
}
if (data.error) {
return data.error;
}
if (data.details) {
return data.details;
}
} catch {
// Inte JSON, försök text
try {
const text = await response.text();
if (text && text.length < 200) {
return text;
}
} catch {
// Inget text-innehål
}
}
// Fallback baserat på HTTP-status
const defaultMessages: Record<number, string> = {
400: 'Ogiltiga data. Kontrollera dina inmatningar.',
401: 'Du är inte autentiserad. Logga in.',
403: 'Du har inte behörighet till detta.',
404: 'Resursen hittades inte.',
409: 'Konflikten med befintlig data.',
422: 'Valideringen misslyckades. Kontrollera dina inmatningar.',
500: 'Serverfel. Försök igen senare.',
503: 'Tjänsten är inte tillgänglig.',
};
return defaultMessages[status] || `Fel (${status}). Försök igen senare.`;
}