Welcome to Our Website

brugerdefinerede fejl, udvidelsesfejl

Når vi udvikler noget, har vi ofte brug for vores egne fejlklasser for at afspejle specifikke ting, der kan gå galt i vores opgaver. For fejl i netværksoperationer har vi muligvis brug for HttpError, til databaseoperationer DbError, til søgning af operationer NotFoundError og så videre.

Vores fejl bør støtte grundlæggende fejl egenskaber som message name og, helst, stack. Men de kan også have andre egenskaber af deres egne, f,, HttpError objekter kan have en statusCode ejendom med en værdi som f.eks. 404 eller 403 eller 500.

JavaScript tillader at bruge throw med noget argument, så teknisk set behøver vores brugerdefinerede fejlklasser ikke at arve fra Error. Men hvis vi arver, bliver det muligt at bruge obj instanceof Error til at identificere fejlobjekter. Så det er bedre at arve fra det.

efterhånden som applikationen vokser, danner vores egne fejl naturligvis et hierarki., For eksempel kan HttpTimeoutError arve fra HttpError og så videre.

Udvidelsesfejl

lad os som eksempel overveje en funktion readUser(json), der skal læse JSON med brugerdata.

Her er et eksempel på, hvordan et gyldigt json kan se:

let json = `{ "name": "John", "age": 30 }`;

Internt, vil vi bruge JSON.parse. Hvis den modtager misdannet json, kaster den SyntaxError., Men selvom json er syntaktisk korrekt, betyder det ikke, at det er en gyldig bruger, ikke? Det kan gå glip af de nødvendige data. For eksempel, kan det ikke have name og age egenskaber, der er afgørende for vores brugere.

vores funktion readUser(json) vil ikke kun læse JSON, men kontrollere (“validere”) dataene. Hvis der ikke er nogen obligatoriske felter, eller formatet er forkert, så er det en fejl. Og det er ikke en SyntaxError, fordi dataene er syntaktisk korrekte, men en anden slags fejl., Vi kalder det ValidationError og oprette en klasse for det. En sådan fejl bør også indeholde oplysninger om det krænkende felt.

voresValidationError klasse skal arve fra den indbyggede Error klasse.

Denne klasse er indbygget, men her er dens omtrentlige kode, så vi kan forstå, hvad vi har at udvide:

lad os Nu arver ValidationError fra det, og prøve det i praksis:

bemærk: i linje (1) vi kalde den forælder constructor., JavaScript kræver, at vi ringer super i børnekonstruktøren, så det er obligatorisk. Den overordnede konstruktør indstillermessage ejendom.

forældrekonstruktøren indstiller ogsånameegenskaben til"Error", så i linjen(2) nulstiller vi den til den rigtige værdi.,

Lad os prøve at bruge det i readUser(json):

try..catch blok i koden ovenfor håndterer både vores ValidationError og den indbyggede SyntaxError fra JSON.parse.

Tag et kig på, hvordan vi bruger instanceof for at kontrollere for den specifikke fejltype i linjen (*).,

Vi kunne også se på err.name, som dette:

// ...// instead of (err instanceof SyntaxError)} else if (err.name == "SyntaxError") { // (*)// ...

instanceof version er meget bedre, fordi vi i fremtiden kommer til at udvide ValidationError, gøre undertyper af det, f.eks. PropertyRequiredError. Og instanceof check vil fortsætte med at arbejde for nye arvende klasser. Så det er fremtidssikret.

det er også vigtigt, at hvis catchopfylder en ukendt fejl, så genovervejer den den i linjen (**)., catch block ved kun, hvordan man håndterer validerings-og syntaksfejl, andre typer (på grund af en skrivefejl i koden eller andre ukendte) skal falde igennem.

yderligere arv

ValidationError klassen er meget generisk. Mange ting kan gå galt. Ejendommen kan være fraværende, eller den kan være i et forkert format (som en strengværdi for age). Lad os lave en mere konkret klasse PropertyRequiredError, præcis for fraværende egenskaber. Det vil bære yderligere oplysninger om ejendommen, der mangler.,

den nye klasse PropertyRequiredError er nem at bruge: vi behøver kun at passere egenskabsnavnet: new PropertyRequiredError(property). Den menneskelige læsbare message genereres af konstruktøren.

Bemærk, atthis.name iPropertyRequiredError constructor igen tildeles manuelt. Det kan blive lidt kedeligt – at tildele this.name = <class name> i hver brugerdefineret fejlklasse. Vi kan undgå det ved at lave vores egen “grundlæggende fejl” klasse, der tildeler this.name = this.constructor.name. Og så arve alle vores brugerdefinerede fejl fra det.,

lad os kalde det MyError.

Her er koden med MyError og andre brugerdefinerede fejl klasser, forenklet:

Nu brugerdefinerede fejl er meget kortere, især ValidationError, som vi er sluppet af med de "this.name = ..." linje i konstruktøren.

indpakning undtagelser

formålet med funktionen readUser i koden ovenfor er “at læse brugerdata”. Der kan forekomme forskellige slags fejl i processen., Lige nu har vi SyntaxError og ValidationError, men i fremtiden readUser funktion kan vokse og sandsynligvis generere andre typer af fejl.

koden, der kalderreadUser, skal håndtere disse fejl. Lige nu bruger den flere if s icatch block, der kontrollerer klassen og håndterer kendte fejl og genkalder de ukendte.

ordningen er sådan:

i koden ovenfor kan vi se to typer fejl, men der kan være flere.,

hvis readUser-funktionen genererer flere slags fejl, skal vi spørge os selv: vil vi virkelig kontrollere for alle fejltyper en efter en hver gang?

ofte er svaret “nej”: vi vil gerne være “et niveau frem for alt det”. Vi vil bare vide, om der var en “datalæsningsfejl” – hvorfor nøjagtigt det skete, er ofte irrelevant (fejlmeddelelsen beskriver det). Eller endnu bedre, vi vil gerne have en måde at få fejloplysningerne på, men kun hvis vi har brug for det.

teknikken, som vi beskriver her, kaldes “indpakningsundtagelser”.,

  1. Vi laver en ny klasse ReadError for at repræsentere en generisk “data læsning” fejl.
  2. funktion readUser vil fange data læsning fejl, der opstår inde i det, som f.eks. ValidationError og SyntaxError, og generere en ReadError i stedet for.
  3. ReadError objekt vil holde henvisningen til den oprindelige fejl i sincause ejendom.,

derefter skal koden, der kalder readUser, kun kontrollere for ReadError, ikke for alle slags datalæsningsfejl. Og hvis det har brug for flere detaljer om en fejl, kan den kontrollere dens cause ejendom.,

Her er den kode, der definerer ReadError og demonstrerer dens anvendelse i readUser og try..catch:

I koden ovenfor, readUser fungerer præcis som beskrevet – fangster syntaks og validering fejl og kaster ReadError fejl, i stedet for (ukendt fejl er rethrown som sædvanlig).

så den ydre kode kontrollerer instanceof ReadError og det er det. Ingen grund til at liste alle mulige fejltyper.,

fremgangsmåden kaldes “indpakning undtagelser”, fordi vi tager “lavt niveau” undtagelser og “wraprap” dem iReadError det er mere abstrakt. Det er meget udbredt i objektorienteret programmering.

resum and

  • Vi kan arve fraError og andre indbyggede fejlklasser normalt. Vi skal bare passe på name ejendom og glem ikke at ringe til super.
  • Vi kan bruge instanceof til at kontrollere for bestemte fejl. Det virker også med arv., Men nogle gange har vi en fejl objekt, der kommer fra en 3.-parts bibliotek, og der er ingen nem måde at få sin klasse. Derefter name ejendom kan bruges til sådanne kontroller.
  • indpakning af undtagelser er en udbredt teknik: en funktion håndterer undtagelser på lavt niveau og skaber fejl på højere niveau i stedet for forskellige lavt niveau. Undtagelser på lavt niveau bliver undertiden egenskaber for det objekt som err.cause i eksemplerne ovenfor, men det er ikke strengt nødvendigt.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *