Javascript er innebygd Error
gir nyttig informasjon, men kan ofte føle seg mangler i klarhet. One-size-fits-all er flott for språket, men vi kan gjøre det bedre i våre egne apps. Det er der tilpassede feil kommer inn.
du har kanskje sett egendefinerte feil når Du bruker Node.js. Node er bygget i feiltyper som AssertionError
, RangeError
, ReferenceError
, SyntaxError
, og SystemError
er alle utvidelser av den innfødte Error
– klassen.
Bruke Error
som en base gir deg all kraften I Javascript implementering pluss ekstra fordeler. Her er bare noen få:
- Egendefinerte feilmeldingsformater.
- Flere egenskaper På Feilobjektet.
- Navngitte feil for å gjøre feilsøking og betinget feilhåndtering enklere.
- Konsekvente feil for bibliotekets forbrukere å referere til.
Utvide feilklassen
for å komme i gang, la oss bruke et generisk eksempel. Vi vil utvide Error
– klassen og bruke super
for å arve funksjonene.
class CustomError extends Error { constructor(...params) { super(...params) // We're spreading `params` as a way to bring all of `Error`'s functionality in. }}
nå, når du throw
en feil, kan du gjøre det med throw new CustomError("Something went wrong...")
. Det gir deg også muligheten til å sjekke feil mot typen:
try { throw new CustomError("Something went wrong")} catch (error) { if (error instance of CustomError) { // do something specifically for that type of error }}
Dette alene gjør ikke mye, annet enn å gi deg en ny feiltype å ringe og se etter. For bedre å forstå hva som kan gjøres, la oss se på hva som kommer som standard på Error
.
- Error.name
- Feil.melding
- Feil.prototype.toString ()
- Feil.prototype.konstruktør()
Ikke mye å jobbe med er det? Bortsett fra konstruktøren og toString
– metoden, er navnet på feilen og meldingen som beskriver feilen de eneste delene vi sannsynligvis vil bruke. I eksemplet ovenfor er message
satt ved å sende «noe gikk galt» som argumentet når du startet feilen.
Heldigvis er de fleste javascript-plattformer som nettleseren og Noden.js har lagt til egne metoder og egenskaper på toppen av de som er oppført. Vi vil fokusere på noen aspekter Av feilimplementeringen Fra V8, Javascript-motoren som driver Chrome og Node.js.
de to interesseområdene er stack
og captureStackTrace
. Som deres navn antyder, de lar deg overflaten stabelen spor. La oss se hvordan det ser ut med et eksempel.
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)}
i dette eksemplet ringer vi Error.captureStackTrace
, hvis plattformen støtter det, for å sikre at et komplett spor legges til vår tilpassede feil. Vi så throw
feilen fra try
blokken, som vil passere kontrollen til catch
blokken.
hvis du kjører koden ovenfor, ser du at den første linjen i stack
er feilens name
og message
.
Our Custom Error: Something went wrong
denne feilen er ikke veldig «dyp», så stakken er for det meste Node.js internals. Hver linje er en» ramme » av stabelen. De inneholder detaljer om plasseringen av feilen i kodebasen.
Nå som vi vet hvordan å lage og ringe en tilpasset feil, la oss gjøre det nyttig.
Tilpasse Feilinnhold
den egendefinerte feilen vi har jobbet med, er bra, men la oss endre den for å gjøre den mer nyttig. Klassen vil være CircuitError
. Vi bruker den til å gi tilpassede feil som kommer fra en bryter. Hvis du ikke er kjent med mønsteret, er det greit. Implementeringsdetaljene til strømbryteren er ikke viktige. Det som er viktig er at vi kan sende litt informasjon inn i feilen, og det vil presentere denne informasjonen til brukeren.
en bryter har en «ÅPEN» tilstand som ikke tillater noe å passere gjennom det i en fast tid. La oss sette vår CircuitError
opp for å inneholde noen detaljer som kan være nyttige for funksjonene som mottar den når staten er 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.` } }}
vår oppdaterte feil gjør noen nye ting, alt i konstruktøren. Argumentene som er bestått, har endret seg (1) for å inkludere state
av bryteren, samt et nextAttempt
tidsstempel for å indikere når bryteren vil begynne å prøve forespørsler igjen.
det setter deretter noen nye egenskaper og oppdaterer meldingen avhengig av verdiene som presenteres. Vi kan teste det ved å kaste en ny versjon av denne feilen.
try { throw new CircuitError("OPEN", Date.now() + 8000)} catch (err) { console.error(err)}
Nå når vi kaster feilen, tar det staten som det første argumentet og et tidsstempel som det andre. For denne demoen vi passerer i tid 8000 millisekunder i fremtiden. Legg merke til at vi også logger feilen selv, i stedet for bare stakken.
Kjører koden vil resultere i noe som følgende:
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}
resultatet er feilnavnet etterfulgt av meldingen på første linje. Da har vi resten av stabelen, etterfulgt av alle egenskapene vi har satt i CircuitError
. Våre forbrukere av denne feilen kan bruke disse dataene til å reagere på feilen. For eksempel:
try { throw new CircuitError("OPEN", Date.now() + 8000)} catch (err) { customLogger(err) if (err.state === "OPEN") { handleOpenState(err.nextAttempt) }}
I Stedet for en generisk feil, har vi nå noe bedre egnet til behovene til vår søknad.
Reagere på feil
Egendefinerte feil er en fin måte å reagere på feil. Det er vanlig å anta at alle feil er uventede, men ved å gi nyttige feil kan du gjøre deres eksistens enklere å håndtere. Ved å gjøre bruk av tilpassede feil, ikke bare kan vi gi brukerne av våre programmer med verdifulle data, men vi presenterer også muligheten til å svare på feiltyper gjennom instance of
tilstand.
Hos Bearer bruker vi tilpassede feil for å standardisere svar i koden vår, gi akkurat den informasjonen du trenger i vår klient, og gjøre våre feil handlingsbare.
hvordan bruker du egendefinerte feil i programmene dine? Ta kontakt med oss @ BearerSH og gi oss beskjed.