Javascript postavený v Error
poskytuje užitečné informace, ale často se může cítit nedostatek jasnosti. One-size-fits-all je skvělé pro jazyk, ale můžeme dělat lépe v našich vlastních aplikací. To je místo, kde přicházejí vlastní chyby.
při použití uzlu jste možná viděli vlastní chyby.js. Uzel je postaven v typech chyb, jako jsou AssertionError
, RangeError
, ReferenceError
, SyntaxError
, a SystemError
jsou všechna rozšíření nativní třídy Error
.
použití Error
jako základ vám dává veškerou sílu implementace JavaScriptu plus další výhody. Zde je jen několik:
- vlastní formáty chybových zpráv.
- další vlastnosti objektu chyby.
- pojmenované chyby pro usnadnění ladění a podmíněného zpracování chyb.
- konzistentní chyby pro spotřebitele knihovny odkazovat.
rozšíření třídy chyb
Chcete-li začít, použijte obecný příklad. Rozšíříme třídu Error
a použijeme super
k zdědění jejích funkcí.
class CustomError extends Error { constructor(...params) { super(...params) // We're spreading `params` as a way to bring all of `Error`'s functionality in. }}
Nyní, když throw
chyba, můžete tak učinit s throw new CustomError("Something went wrong...")
. To také vám dává možnost kontrolovat chyby proti typu:
try { throw new CustomError("Something went wrong")} catch (error) { if (error instance of CustomError) { // do something specifically for that type of error }}
to samo o sobě nedělá mnoho, kromě toho, že vám dá nový typ chyby, který chcete volat a zkontrolovat. Abychom lépe porozuměli tomu, co lze udělat, podívejme se na to, co přijde standard na Error
.
- Error.name
- Chyba.zpráva
- chyba.prototyp.toString ()
- chyba.prototyp.konstruktér()
není s čím pracovat, že? Kromě konstruktoru a metody toString
jsou název chyby a zpráva popisující chybu jedinými částmi, které pravděpodobně použijeme. Ve výše uvedeném příkladu je message
nastaveno předáním „něco se pokazilo“ jako argumentu při instanci chyby.
naštěstí většina platforem javascript, jako je prohlížeč a uzel.js přidaly své vlastní metody a vlastnosti nad uvedené. Zaměříme se na několik aspektů implementace chyb z V8, JavaScript engine pohánějící Chrome a Node.js.
dvě oblasti zájmu jsou stack
a captureStackTrace
. Jak jejich názvy napovídají, umožňují vám povrch stopy zásobníku. Podívejme se, jak to vypadá na příkladu.
class CustomError extends Error { constructor(...args) { super(...args) if (Error.captureStackTrace) { Error.captureStackTrace(this, CustomError) } this.name = "Our Custom Error" }}try { throw new CustomError("Something went wrong")} catch (err) { console.error(err.stack)}
v tomto příkladu voláme Error.captureStackTrace
, pokud to platforma podporuje, abychom zajistili, že k naší vlastní chybě bude přidána úplná stopa. Pak throw
chybu z bloku try
, který předá kontrolu bloku catch
.
pokud spustíte výše uvedený kód, uvidíte, že první řádek stack
je chyba name
a message
.
Our Custom Error: Something went wrong
tato chyba není příliš „hluboká“ , takže zásobník je většinou uzel.js interní. Každý řádek je jeden “ rám “ zásobníku. Obsahují podrobnosti o umístění chyby v kódové základně.
Nyní, když víme, jak vytvořit a zavolat vlastní chybu, udělejme ji užitečnou.
přizpůsobení obsahu chyby
vlastní chyba, se kterou jsme pracovali, je v pořádku, ale změníme ji, aby byla užitečnější. Třída bude CircuitError
. Použijeme jej k poskytnutí vlastních chyb pocházejících z jističe. Pokud nejste obeznámeni se vzorem, to je v pořádku. Podrobnosti o implementaci jističe nejsou důležité. Důležité je, že do chyby můžeme předat některé informace a tyto informace předloží uživateli.
jistič má „otevřený“ stav, který neumožňuje, aby jím po určitou dobu něco procházelo. Nastavme náš CircuitError
tak, aby obsahoval některé podrobnosti, které by mohly být užitečné pro funkce, které jej přijímají, když je stav OPEN
.
class CircuitError extends Error { // 1 constructor(state, nextAttempt, ...params) { super(...params) if (Error.captureStackTrace) { Error.captureStackTrace(this, CircuitError) } this.name = "CircuitError" this.state = state // 2 this.message = `The Circuit is ${state}.` // 3 if (nextAttempt) { this.timestamp = Date.now() this.nextAttempt = nextAttempt this.message += ` Next attempt can be made in ${this.nextAttempt - this.timestamp}ms.` } }}
naše aktualizovaná chyba dělá několik nových věcí, vše v konstruktoru. Předané argumenty se změnily (1) tak, aby zahrnovaly state
jističe a také nextAttempt
časové razítko, které indikuje, kdy se jistič začne znovu pokoušet.
poté nastaví několik nových vlastností a aktualizuje zprávu v závislosti na prezentovaných hodnotách. Můžeme to vyzkoušet tím, že hodíme novou verzi této chyby.
try { throw new CircuitError("OPEN", Date.now() + 8000)} catch (err) { console.error(err)}
Nyní, když hodíme chybu, vezme stav jako první argument a časové razítko jako druhé. Pro toto demo míjíme v čase 8000 milisekund v budoucnu. Všimněte si, že také zaznamenáváme samotnou chybu, spíše než jen zásobník.
spuštění kódu bude mít za následek něco jako následující:
CircuitError : The Circuit is OPEN. Next attempt can be made in 6000ms. at Object.<anonymous> (/example.js:21:9) at Module._compile (internal/modules/cjs/loader.js:1063:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1103:10) at Module.load (internal/modules/cjs/loader.js:914:32) at Function.Module._load (internal/modules/cjs/loader.js:822:14) at Function.Module.runMain (internal/modules/cjs/loader.js:1143:12) at internal/main/run_main_module.js:16:11 { name: 'Circuit Error', state: 'OPEN', message: 'The Circuit is OPEN. Next attempt can be made in 6000ms.', timestamp: 1580242308919, nextAttempt: 1580242314919}
výsledkem je název chyby následovaný zprávou na prvním řádku. Pak máme zbytek zásobníku, následovaný všemi vlastnostmi, které jsme nastavili v CircuitError
. Naši spotřebitelé této chyby by mohli tato data použít k reakci na chybu. Například:
try { throw new CircuitError("OPEN", Date.now() + 8000)} catch (err) { customLogger(err) if (err.state === "OPEN") { handleOpenState(err.nextAttempt) }}
místo obecné chyby máme nyní něco, co lépe vyhovuje potřebám naší aplikace.
reakce na selhání
vlastní chyby jsou skvělý způsob, jak reagovat na selhání. Je běžné předpokládat, že všechny chyby jsou neočekávané,ale poskytnutím užitečných chyb můžete usnadnit jejich existenci. Využitím vlastních chyb můžeme nejen poskytnout uživatelům našich aplikací cenná data,ale také prezentovat schopnost reagovat na typy chyb prostřednictvím podmínky instance of
.
na doručitele používáme vlastní chyby ke standardizaci odpovědí v našem kódu, poskytnutí informací, které potřebujete v našem klientovi, a k tomu, aby naše chyby byly použitelné.
jak používáte vlastní chyby ve svých aplikacích? Spojte se s námi @BearerSH a dejte nám vědět.