Welcome to Our Website

vlastní chyby, rozšíření chyby

Když něco vyvíjíme, často potřebujeme vlastní chybové třídy, aby odrážely konkrétní věci, které se mohou v našich úkolech pokazit. Za chyby v provozu sítě můžeme třeba HttpError, pro databázové operace DbError, pro hledání operace NotFoundError, a tak dále.

Naše chyby by měly podporovat základní chyba vlastnosti, jako je message name a, pokud možno, stack. Mohou však mít i jiné vlastní vlastnosti, např., HttpError objekty mohou mít statusCode vlastnost s hodnotou, jako je 404 nebo 403 nebo 500.

JavaScript umožňuje používatthrow s jakýmkoli argumentem, takže technicky naše vlastní třídy chyb nemusí dědit zError. Pokud však zdědíme, je možné použítobj instanceof Error k identifikaci chybových objektů. Takže je lepší dědit z toho.

jak aplikace roste, naše vlastní chyby přirozeně tvoří hierarchii., Například HttpTimeoutError může dědit z HttpError a tak dále.

rozšíření chyby

jako příklad uvažujme funkci readUser(json), která by měla číst JSON s uživatelskými daty.

Tady je příklad toho, jak platné json může vypadat:

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

Interně, budeme používat JSON.parse. Pokud obdrží chybně json, hodí SyntaxError., Ale i když jejson syntakticky správný, neznamená to, že je to platný uživatel, že? Může chybět potřebná data. Například, nemusí mít name age vlastnosti, které jsou nezbytné pro naše uživatele.

Naše funkce readUser(json) budou nejen číst, JSON, ale kontrola („validovat“) data. Pokud nejsou požadovaná pole nebo formát je špatný, pak je to chyba. A to není SyntaxError, protože data jsou syntakticky správná, ale jiný druh chyby., Nazveme to ValidationError a vytvoříme pro ni třídu. Chyba tohoto druhu by také měla obsahovat informace o přestupkovém poli.

našeValidationError třída by měla dědit z vestavěné třídy Error.

ta třída je postavena-in, ale zde je jeho přibližná kód, takže můžeme pochopit, co jsme rozšíření:

Teď pojďme zdědit ValidationError z toho a zkuste to v akci:

Prosím poznámka: v řádku (1) nazýváme rodič konstruktor., JavaScript vyžaduje, abychom volali super v dětském konstruktoru, takže je to povinné. Nadřazený Konstruktor nastaví vlastnost message.

rodič konstruktor také nastaví name vlastnost "Error", tak v řádku (2) obnovit jej na správnou hodnotu.,

zkusme použít to v readUser(json):

try..catch blok v kódu výše zpracovává obě naše ValidationError a postaven-v SyntaxError JSON.parse.

podívejte se, jak používáme instanceof pro kontrolu konkrétního typu chyby v řádku (*).,

Můžeme se také podívat na err.name, například:

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

instanceof verze je mnohem lepší, protože v budoucnu budeme stále rozšiřovat ValidationError, aby podtypy, jako je PropertyRequiredError. Ainstanceof kontrola bude i nadále pracovat pro nové dědické třídy. To je důkaz budoucnosti.

také je důležité, že pokud catch splňuje neznámou chybu,přehodnotí ji v řádku (**)., Blok catch ví, jak zvládnout chyby validace a syntaxe, jiné druhy (kvůli překlepu v kódu nebo jiné neznámé) by měly propadnout.

další dědičnost

třídaValidationError je velmi obecná. Mnoho věcí se může pokazit. Vlastnost může chybět nebo může být ve špatném formátu (jako hodnota řetězce pro age). Udělejme konkrétnější třídu PropertyRequiredError, přesně pro chybějící vlastnosti. Bude obsahovat další informace o majetku, který chybí.,

nová třída PropertyRequiredError se snadno používá: stačí předat název vlastnosti: new PropertyRequiredError(property). Čitelný message je generován konstruktorem.

Upozorňujeme, že this.name v konstruktor je opět přiřazen ručně. To může být trochu únavné – přiřadit this.name = <class name> v každé vlastní třídě chyb. Můžeme se tomu vyhnout tím, že uděláme vlastní třídu „základní chyby“, která přiřadí this.name = this.constructor.name. A pak z toho zdědí všechny naše vlastní chyby.,

říkejme tomu MyError.

Zde je kód MyError a další vlastní chybovou tříd, zjednodušená:

Nyní vlastní chyby jsou mnohem kratší, zejména ValidationError, jak jsme se zbavili "this.name = ..." řádek v konstruktoru.

výjimky pro balení

účelem funkce readUser ve výše uvedeném kódu je „Číst uživatelská data“. V procesu se mohou vyskytnout různé druhy chyb., Teď máme SyntaxError ValidationError, ale v budoucnu readUser funkce může růst a pravděpodobně vytvářet jiné druhy chyb.

kód, který volá readUser, by měl tyto chyby zpracovat. Teď to používá více ifcatch blok, podívejte se na třídy a zvládnout známé chyby a rethrow neznámé ty.

schéma je následující:

v kódu výše vidíme dva typy chyb, ale může jich být více.,

Pokud funkcereadUser generuje několik druhů chyb, měli bychom se ptát sami sebe: opravdu chceme zkontrolovat všechny typy chyb jeden po druhém pokaždé?

často je odpověď „Ne“: chtěli bychom být „o jednu úroveň výše“. Chceme jen vědět, zda došlo k „chybě čtení dat“ – proč přesně se to stalo, je často irelevantní (chybová zpráva ji popisuje). Nebo ještě lépe, chtěli bychom mít způsob, jak získat podrobnosti o chybě, ale pouze v případě, že potřebujeme.

technika, kterou zde popisujeme, se nazývá „balicí výjimky“.,

  1. vytvoříme novou třídu ReadError představuje generický „čtení dat“ chyba.
  2. funkce readUser bude chytat čtení dat chyby, které se vyskytují uvnitř, například ValidationError SyntaxError a generovat ReadError místo.
  3. ReadError objekt ponechá odkaz na původní chybu ve své vlastnosti cause.,

Pak kód, který volá readUser bude mít pouze zkontrolovat ReadError, ne pro každý druh dat, chyby při čtení. A pokud potřebuje více podrobností o chybě,může zkontrolovat vlastnostcause.,

Zde je kód, který definuje ReadError a demonstruje jeho použití v readUser try..catch:

V kódu výše, readUser funguje přesně tak, jak je popsáno úlovky syntaxe a chyby ověření a hody ReadError chyby místo (neznámé chyby jsou rethrown jako obvykle).

takže vnější kód kontroluje instanceof ReadError a to je vše. Není třeba uvádět všechny možné typy chyb.,

přístup se nazývá „balicí výjimky“, protože bereme výjimky“ nízké úrovně „a“ zabalíme“je do ReadError to je abstraktnější. Je široce používán v objektově orientovaném programování.

shrnutí

  • můžeme dědit z Error a dalších vestavěných chybových tříd normálně. Stačí se postarat o vlastnost name a nezapomeňte zavolat super.
  • můžeme použítinstanceof pro kontrolu konkrétních chyb. Pracuje také s dědictvím., Ale někdy máme chybový objekt pocházející z knihovny 3. strany a není snadný způsob, jak získat jeho třídu. Pak name vlastnost může být použita pro takové kontroly.
  • balení výjimek je rozšířená technika: funkce zpracovává výjimky nízké úrovně a vytváří chyby vyšší úrovně namísto různých nízkoúrovňových. Výjimky na nízké úrovni se někdy stávají vlastnostmi tohoto objektu, jako je err.cause ve výše uvedených příkladech, ale to není nezbytně nutné.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *