Welcome to Our Website

aangepaste fouten, uitbreiding fout

wanneer we iets ontwikkelen, hebben we vaak onze eigen foutklassen nodig om specifieke dingen weer te geven die fout kunnen gaan in onze taken. Voor fouten in netwerk operaties kunnen we HttpError nodig hebben, voor database operaties DbError, Voor zoek operaties NotFoundError enzovoort.

onze fouten moeten basisfouteigenschappen ondersteunen zoals message, name en, bij voorkeur, stack. Maar ze kunnen ook andere eigenschappen van hun eigen hebben, bijv., HttpErrorobjecten kunnen een statusCodeeigenschap hebben met een waarde als 404of 403of 500.

JavaScript maakt het mogelijk om throw te gebruiken met elk argument, dus technisch gezien hoeven onze aangepaste foutklassen niet te erven van Error. Maar als we erven, dan wordt het mogelijk om obj instanceof Error te gebruiken om foutobjecten te identificeren. Dus het is beter om ervan te erven.

naarmate de toepassing groeit, vormen onze eigen fouten natuurlijk een hiërarchie., Bijvoorbeeld, HttpTimeoutError kan erven van HttpError, enzovoort.

Uitbreidingsfout

laten we als voorbeeld een functie readUser(json) overwegen die JSON met gebruikersgegevens zou moeten lezen.

Hier is een voorbeeld van hoe een geldige json eruit kan zien:

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

intern gebruiken we JSON.parse. Als het misvormde json ontvangt, dan gooit het SyntaxError., Maar zelfs als json syntactisch correct is, betekent dat niet dat het een geldige gebruiker is, toch? Het kan de benodigde gegevens missen. Bijvoorbeeld, het kan niet name en age eigenschappen hebben die essentieel zijn voor onze gebruikers.

onze functie readUser(json) zal niet alleen JSON lezen, maar de gegevens controleren (“valideren”). Als er geen verplichte velden zijn, of het formaat is verkeerd, dan is dat een fout. En dat is geen SyntaxError, omdat de gegevens syntactisch correct zijn, maar een ander soort fout., We noemen het ValidationError en maken er een klasse voor aan. Een dergelijke fout moet ook de informatie over het gewraakte veld bevatten.

onze ValidationError klasse moet erven van de ingebouwde Error klasse.

die klasse is ingebouwd, maar hier is de geschatte code zodat we kunnen begrijpen wat we aan het uitbreiden zijn:

laten we nu ValidationError van het overnemen en het in actie proberen:

let op: in de regel (1) noemen we de bovenliggende constructor., JavaScript vereist dat we super aanroepen in de onderliggende constructor, dus dat is verplicht. De bovenliggende constructor stelt de eigenschap message in.

de bovenliggende constructor stelt ook de eigenschap name in op "Error", dus in de regel (2) zetten we het terug naar de juiste waarde.,

laten we proberen het te gebruiken in readUser(json):

Het try..catch blok in de bovenstaande code behandelt zowel onze ValidationError en de ingebouwde SyntaxError van JSON.parse.

kijk eens hoe we instanceof gebruiken om te controleren op het specifieke fouttype in de regel (*).,

we zouden ook kunnen kijken naar err.name, als volgt:

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

de instanceofversie is veel beter, omdat we in de toekomst div id=”2a9eadcca5″>, maak er subtypes van, zoalsPropertyRequiredError. En instanceof controle zal blijven werken voor nieuwe ervende klassen. Dus dat is toekomstbestendig.

ook is het belangrijk dat als catch een onbekende fout ontmoet, het deze opnieuw in de regel (**)hergroeit., Hetcatch blok Weet alleen hoe om te gaan met validatie en syntaxis fouten, andere soorten (als gevolg van een typefout in de code of andere onbekende) zou moeten vallen door.

verdere overerving

deValidationError klasse is zeer generiek. Veel dingen kunnen fout gaan. De eigenschap kan afwezig zijn of in een verkeerd formaat (zoals een tekenreekswaarde voor age). Laten we een meer concrete klasse PropertyRequiredError maken, precies voor afwezige eigenschappen. Het zal extra informatie bevatten over de woning die ontbreekt.,

de nieuwe klasse PropertyRequiredError is eenvoudig te gebruiken: we hoeven alleen de eigenschapsnaam door te geven: new PropertyRequiredError(property). De voor mensen leesbare message wordt gegenereerd door de constructor.

merk op dat this.name in PropertyRequiredError constructor opnieuw handmatig wordt toegewezen. Dat kan een beetje vervelend worden-om this.name = <class name> toe te wijzen in elke aangepaste foutklasse. We kunnen dit vermijden door onze eigen “basic error” klasse te maken die this.name = this.constructor.nametoewijst. En dan erven al onze aangepaste fouten van het.,

laten we het MyErrornoemen.

Hier is de code met MyError en andere aangepaste foutklassen, vereenvoudigd:

nu zijn aangepaste fouten veel korter, vooral ValidationError, omdat we de "this.name = ..." regel in de constructor kwijt zijn.

Wrapping exceptions

Het doel van de functiereadUser in de bovenstaande code is “de gebruikersgegevens lezen”. Er kunnen verschillende soorten fouten optreden in het proces., Op dit moment hebben we SyntaxError en ValidationError, maar in de toekomst readUser kan de functie groeien en waarschijnlijk andere soorten fouten genereren.

de code die readUser aanroept, moet deze fouten verwerken. Op dit moment gebruikt het meerdere ifs in het catch blok, die de klasse controleren en bekende fouten verwerken en de onbekende hertrouwen.

het schema is als volgt:

in de bovenstaande code kunnen we twee soorten fouten zien, maar er kunnen er meer zijn.,

als de functie readUser meerdere soorten fouten genereert, dan moeten we ons afvragen: willen we echt elke keer één voor één op alle fouttypen controleren?

vaak is het antwoord “nee”: we willen”één niveau boven dat alles” zijn. We willen gewoon weten of er een “data reading error” – waarom precies het gebeurde is vaak irrelevant (de foutmelding beschrijft het). Of, nog beter, we zouden graag een manier hebben om de foutdetails te krijgen, maar alleen als het nodig is.

de techniek die we hier beschrijven heet “wrapping exceptions”.,

  1. We maken een nieuwe klasse ReadError om een algemene” data reading ” fout weer te geven.
  2. de functie readUser vangt fouten in het lezen van gegevens, zoals ValidationError en SyntaxError, en genereert in plaats daarvan een ReadError.
  3. hetReadError object behoudt de verwijzing naar de oorspronkelijke fout in zijncause eigenschap.,

dan hoeft de code die readUser aanroept alleen te controleren op ReadError, niet voor alle soorten fouten in het lezen van gegevens. En als het meer details van een fout nodig heeft, kan het zijn cause eigenschap controleren.,

Hier is de code die bepaalt ReadError en demonstreert het gebruik in readUser en try..catch:

In de code hierboven, readUser werkt precies zoals beschreven – de vangsten syntaxis en validatie fouten en gooit ReadError fouten in plaats van (onbekend fouten zijn rethrown zoals gewoonlijk).

dus de buitenste code controleert instanceof ReadError en dat is het. Het is niet nodig om alle mogelijke fouttypen op te sommen.,

De aanpak wordt “wrapping exceptions” genoemd, omdat we “low level” exceptions nemen en ze “wrap” in ReadError dat is abstracter. Het wordt veel gebruikt in objectgeoriënteerd programmeren.

samenvatting

  • We kunnen normaal van Error en andere ingebouwde foutklassen overnemen. We moeten alleen de eigenschap name afhandelen en vergeet niet superaan te roepen.
  • we kunnen instanceof gebruiken om bepaalde fouten te controleren. Het werkt ook met erfenis., Maar soms hebben we een fout object afkomstig van een 3rd-party bibliotheek en er is geen gemakkelijke manier om zijn klasse te krijgen. Dan kan name eigenschap gebruikt worden voor dergelijke controles.
  • wrapping exceptions is een wijdverbreide techniek: een functie behandelt low-level exceptions en creëert fouten op een hoger niveau in plaats van verschillende low-level ones. Uitzonderingen op laag niveau worden soms eigenschappen van dat object zoals err.cause in de voorbeelden hierboven, maar dat is niet strikt vereist.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *