Slik bygger du robuste API-kall i frontend med fetch og god feilhåndtering

Flere og flere bruker JavaScript i nettleseren til å hente data fra API-er, for eksempel fra egen backend eller tredjepartstjenester. Det fungerer fint så lenge nettet er stabilt og API-et svarer pent.
Utfordringen starter når ting går galt: ustabilt nett, trege svar, rare feilkoder eller uventet respons. Da er det forskjellen på et halvferdig og et robust frontend-prosjekt blir tydelig.
Hvorfor robuste API-kall er viktig i frontend
I en moderne webapplikasjon er API-kall ofte kjernefunksjonalitet. Hvis disse svikter, oppfatter brukeren gjerne hele løsningen som upålitelig, uansett hvor pen designen er.
God håndtering av API-kall gir deg blant annet tydeligere feilmeldinger til brukeren, færre «hengende» spinnere, enklere feilsøking og kode som er lettere å vedlikeholde over tid.
Grunnmuren: fetch, async/await og tydelige responstyper
Moderne nettlesere har innebygdfetchfor HTTP-kall. Sammen medasync/awaitgjør det koden mer lesbar enn tradisjonelle callback-mønstre.
Et minimalt eksempel på et GET-kall mot et JSON-API kan se slik ut:
Eksempel:
async function hentBrukere() {
const respons = await fetch('/api/brukere');
const data = await respons.json();
return data;
}
Dette fungerer, men mangler viktige ting: ingen sjekk av HTTP-status, ingen håndtering av nettverksfeil og ingen tidsavbrudd. La oss forbedre det steg for steg.
Håndter HTTP-feil eksplisitt
fetchkaster ikke feil automatisk hvis API-et svarer med for eksempel 404 eller 500. Kallet regnes som «vellykket» så lenge nettverket svarer, selv om serveren returnerer en feilstatus.
Derfor bør du alltid sjekkeresponse.okog kaste en egen feil hvis statusen ikke er innenfor 200-299:
Eksempel med status-sjekk:
async function hentBrukere() {
const respons = await fetch('/api/brukere');
if (!respons.ok) {
throw new Error(`Serverfeil: ${respons.status}`);
}
return respons.json();
}
Nå vil koden som kallerhentBrukerekunne fange opp feilen i entry/catch, og du kan vise en forståelig melding til brukeren eller logge detaljene.
Try/catch rundt selve API-kallet
Alt som kan gå galt ved henting og parsing av data bør ligge inne i entry/catch-blokk. Da får du samlet håndtering av både nettverksfeil, JSON-feil og egne kastede feil.
Eksempel med try/catch:
async function trygtHentBrukere() {
try {
const respons = await fetch('/api/brukere');
if (!respons.ok) {
throw new Error(`Serverfeil: ${respons.status}`);
}
return await respons.json();
} catch (feil) {
console.error('Klarte ikke å hente brukere', feil);
throw feil;
}
}
Her logger vi feilen ett sted og sender den videre. UI-laget kan da avgjøre om brukeren skal se en feilmelding, en fallback-visning eller få valget om å prøve igjen.
Gi brukeren tydelig tilbakemelding i UI
Teknisk korrekte API-kall er ikke nok, brukeren må også forstå hva som skjer. Et enkelt mønster er å skille mellom tre tilstander:laster,ferdig med dataogfeil.
I en typisk komponentbasert frontend (React, Vue, Svelte eller lignende) vil dette ofte bestå av tre enkle flagg:isLoading,errorogdata. Prinsippet er det samme uavhengig av rammeverk.
Typisk flyt:
- SettisLoading = truefør du starter API-kallet.
- Når du får data, settisLoading = falseog lagre dataene.
- Ved feil, settisLoading = falseog lagre en kort feilmelding.
Pass på at feiltekster er forståelige: «Noe gikk galt ved henting av data. Sjekk tilkoblingen og prøv igjen.» er ofte bedre enn tekniske detaljer.
Tidsavbrudd: unngå evig hengende forespørsler

Nettverkskall kan i noen tilfeller bli hengende lenge, for eksempel ved dårlig mobildekning. Uten tidsavbrudd vil brukeren bare se en spinner som aldri forsvinner.
Du kan lage et tidsavbrudd rundt fetch ved å kombinereAbortControllermed ensetTimeout:
Eksempel på fetch med tidsavbrudd:
async function fetchMedTimeout(url, { timeoutMs = 8000, ...options } = {}) {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeoutMs);
try {
const respons = await fetch(url, { ...options, signal: controller.signal });
return respons;
} finally {
clearTimeout(id);
}
}
Deretter kan du brukefetchMedTimeouti stedet for vanlig fetch, og gi brukeren en egen melding hvis feilen skyldes tidsavbrudd.
Gjenta forsøk forsiktig med «retry»-logikk
Noen feil er midlertidige, for eksempel korte nettverksglipp. Da kan det være nyttig å prøve automatisk på nytt et begrenset antall ganger.
Et enkelt mønster er å ha en funksjon som prøver flere ganger med økende ventetid mellom forsøkene:
Eksempel på enkel retry:
async function fetchMedRetry(url, forsok = 3) {
let sisteFeil;
for (let i = 0; i < forsok; i++) {
try {
const respons = await fetch(url);
if (!respons.ok) {
throw new Error(`Serverfeil: ${respons.status}`);
}
return respons;
} catch (feil) {
sisteFeil = feil;
await new Promise(r => setTimeout(r, 200 * (i + 1)));
}
}
throw sisteFeil;
}
Bruk retry med måte, og helst bare for kall som er trygge å gjenta, for eksempel lesing av data. For operasjoner som lagrer eller oppdaterer bør du være mer forsiktig for å unngå duplikater.
Valider responsen før du bruker den
Det er lett å anta at API-et alltid sender akkurat de feltene du forventer. I virkeligheten kan felter mangle, ha annen type enn planlagt eller komme i en annen struktur etter en oppdatering på serveren.
I frontend bør du derfor alltid sjekke at strukturen gir mening før du viser data. For kritiske deler kan du innføre enkel validering, for eksempel kontrollere at du faktisk har en liste, at objekter har det viktigste feltet, eller at tall faktisk er tall.
I mer komplekse løsninger kan det være aktuelt å bruke egne valideringsbiblioteker, men prinsippet er det samme: stol ikke blindt på at responsen er perfekt.
Tre vanlige feil som skaper skjøre API-integrasjoner
Til slutt noen feil som dukker opp i mange kodebaser, og hvilke forbedringer du kan gjøre:
- Altfor generelle feilmeldinger:«Noe gikk galt» hjelper verken brukeren eller deg. Del feilen i en kort brukertekst og mer detaljerte logger.
- Manglende abort når komponenter unmountes:Hvis du bruker framework med komponenter, bør lange forespørsler avbrytes når brukeren navigerer bort.
- Kodekopiering i stedet for felles hjelpefunksjoner:Når samme fetch-mønster skrives om og om igjen, er det lett å få ulik feilhåndtering. Lag heller et lite «API-lag» med gjenbrukbare funksjoner.
Oppsummering: bygg et lite, men solid API-lag
Robuste API-kall i frontend handler ikke om avanserte mønstre, men om noen enkle vaner: sjekk HTTP-status, bruk try/catch, lag tydelige UI-tilstander, håndter tidsavbrudd og vær forsiktig med retry.
Ved å samle disse rutinene i et lite API-lag får du mindre duplisert kode, færre uforståelige feil for brukeren og en løsning som tåler at nettet og serveren ikke alltid oppfører seg perfekt.









0 kommentarer