Praktisk feilhåndtering i Python: slik skriver du kode som tåler virkeligheten

Mye kode fungerer helt fint på utviklerens egen maskin, men kollapser ved første feil hos en ekte bruker. Grunnen er ofte svak eller fraværende feilhåndtering. Resultatet blir kryptiske krasj, tapte data og frustrasjon.
I denne artikkelen ser vi på hvordan du kan bygge tryggere Python-programmer med gjennomtenkt feilhåndtering. Målet er at du skal forstå hva som kan gå galt, hvor du bør gripe inn, og hvordan du skriver kode som gir nyttige feilmeldinger i stedet for å bare stoppe.
Hva feilhåndtering egentlig handler om
Feilhåndtering er ikke magi, det er bare en plan for hva som skal skje når ting ikke går som forventet. Filen finnes ikke, API-et svarer ikke, brukeren skriver tekst der du forventer et tall, eller databasen er nede.
I Python bruker du hovedsakeligtry,except,elseogfinallyfor å håndtere feil. Tanken er enkel: prøv noe, fang spesifikke feil, rydd opp, og fortell hva som skjedde på en ryddig måte.
Grunnmønsteret: try, except, else, finally
La oss starte med et lite, realistisk eksempel: lese et tall fra en fil og regne med det.
Uten feilhåndtering kan det se slik ut:
Eksempel uten feilhåndtering
with open("verdi.txt") as f:
innhold = f.read()
verdi = int(innhold)
resultat = 100 / verdi
print(resultat)
Her kan mye gå galt: filen finnes ikke, filen inneholder ikke et tall, eller tallet er 0. Programmet vil da krasje med en traceback som kan være vanskelig å tolke for en ikke-teknisk bruker.
Samme eksempel med enkel feilhåndtering
try:
with open("verdi.txt") as f:
innhold = f.read()
verdi = int(innhold)
resultat = 100 / verdi
except FileNotFoundError:
print("Filen 'verdi.txt' ble ikke funnet.")
except ValueError:
print("Innholdet i filen må være et heltall.")
except ZeroDivisionError:
print("Tallet i filen kan ikke være 0.")
else:
print("Resultat:", resultat)
Hva skjer her
- try: alt som kan feile samles her.
- except FileNotFoundError: kjøres bare hvis filen mangler.
- except ValueError: kjøres hvis konvertering til int feiler.
- except ZeroDivisionError: fanger deling på null.
- else: kjøres bare hvis ingen feil oppstod.
Hvorfor du bør unngå “bare fang alt”
En vanlig felle er å skrive:
try:
kritisk_kode()
except Exception:
print("Noe gikk galt")
Det ser trygt ut, men problemet er at du skjuler informasjon du ofte trenger for å rette feilen. Du kan også ende opp med å skjule programmeringsfeil, ikke bare forventede problemer som fil som mangler eller dårlig input.
Et bedre mønster er:
- Fangkonkreteunntak du forventer.
- La ukjente feil boble opp, spesielt under utvikling.
- Logg detaljene, men vis en forenklet og forståelig melding til sluttbruker.
Lag egne feilklasser for ryddigere kode
I litt større prosjekter blir det tungt å håndtere mange forskjellige innebygde unntak direkte overalt. Da er det nyttig å lage egne feilklasser for ditt domene.
Eksempel på egne unntak
class PrisFeil(Exception):
pass
class LagerFeil(Exception):
pass
def beregn_totalpris(pris_per_enhet, antall):
if pris_per_enhet < 0:
raise PrisFeil("Pris kan ikke være negativ.")
if antall < 0:
raise LagerFeil("Antall kan ikke være negativt.")
return pris_per_enhet * antall
Når du kaller denne funksjonen i en annen del av programmet, kan du samle håndteringen:
try:
total = beregn_totalpris(100, -1)
except PrisFeil as e:
print("Prisrelatert feil:", e)
except LagerFeil as e:
print("Lagerrelatert feil:", e)
Fordelen er at du skiller mellom ulike typer logikkfeil på en tydelig måte, og du har ett sted i koden der du bestemmer når feil skal oppstå.
Bruk finally til opprydding

Noen ressurser må ryddes opp uansett om det oppstår feil eller ikke. Eksempler kan være filhåndtak, databindings eller midlertidige filer.
Eksempel med finally
logg = open("logg.txt", "a")
try:
logg.write("Starter jobbn")
gjør_noe_kritisk()
except Exception as e:
logg.write(f"Feil: {e}n")
raise
finally:
logg.close()
Her er vi sikre på at filen alltid blir lukket, også hvis det skjer noe uventet. I mange tilfeller kan du brukewithi stedet, menfinallyer nyttig der det ikke er tilgjengelig.
Gi menneskelige feilmeldinger, logg detaljer for deg selv
En profesjonell løsning skiller mellom informasjon sluttbruker trenger, og informasjon du trenger som teknisk ansvarlig. Brukeren trenger ofte bare å vite hva som gikk galt, hva det betyr for dem, og hva de kan gjøre.
Du kan kombinere dette ved å logge detaljene og vise en kortere melding i grensesnittet:
import logging
logging.basicConfig(filename="app.log", level=logging.ERROR)
def kjør_oppgave():
try:
kritisk_operasjon()
except Exception as e:
logging.exception("Uventet feil i kjør_oppgave")
print("Det oppstod en feil. Prøv igjen senere, eller kontakt støtte om problemet fortsetter.")
Viktige prinsipper
- Ikke vis hele tracebacks til sluttbruker med mindre det er et verktøy for teknisk publikum.
- Logg alltid uventede feil på et sted du finner igjen.
- Gi korte, konkrete meldinger med mulig neste steg.
Når du bør feile tidlig i stedet for å “redde” alt
Noen feil bør stoppes tidlig i koden i stedet for å forsøke å håndtere dem langt senere. Det gjelder spesielt når input er ulogisk eller mangler viktige felt.
Eksempel på tidlig validering
def lag_bruker(navn, alder):
if not navn:
raise ValueError("Navn kan ikke være tomt.")
if alder < 0:
raise ValueError("Alder kan ikke være negativ.")
# resten av logikken her
Ved å validere i starten slipper du å jage mystiske feil senere i prosessen. Det gjør også koden lettere å teste, siden du tydelig kan sjekke at feil input gir riktig unntak.
Slik kommer du i gang i egne prosjekter
Det er lett å bli overveldet og tenke at du må skrive “perfekt” feilhåndtering overalt. Det trenger du ikke. Start heller med noen konkrete forbedringer i et eksisterende prosjekt.
En praktisk fremgangsmåte:
- Finn funksjoner som leser filer, kaller API-er eller snakker med databaser.
- Legg rundttry/exceptmed spesifikke unntak som kan oppstå.
- Logg detaljerte feil og vis ryddige meldinger til sluttbruker.
- Legg til inputvalidering i funksjoner som tar imot data utenfra.
- Etter hvert: vurder egne feilklasser for domenet ditt.
Hvis du gjør dette gradvis vil koden din tåle langt mer av den uforutsigbare virkeligheten, uten at alt kollapser ved første feil.









0 kommentarer