Personalizarea erorilor în nod.JS

Javascript construit în Error oferă informații utile, dar se pot simți de multe ori lipsit de claritate. One-size-fits-all este mare pentru limba, dar putem face mai bine în propriile noastre aplicații. Aici intervin Erorile personalizate.

este posibil să fi văzut erori personalizate atunci când se utilizează Node.js. Node construit în tipuri de erori, cum ar fi AssertionError, RangeError, ReferenceError, SyntaxError, și SystemError sunt toate extensii ale clasei native Error.

utilizarea Error ca bază vă oferă toată puterea implementării Javascript plus beneficii suplimentare. Iată doar câteva:

  • formate de mesaje de eroare personalizate.
  • proprietăți suplimentare pe obiectul de eroare.
  • erori numite pentru a facilita depanarea și manipularea erorilor condiționate.
  • erori consistente pentru consumatorii de bibliotecă la referință.

extinderea clasei de eroare

pentru a începe, să folosim un exemplu generic. Vom extinde clasa Error și vom folosi super pentru a moșteni funcțiile sale.

class CustomError extends Error { constructor(...params) { super(...params) // We're spreading `params` as a way to bring all of `Error`'s functionality in. }}

acum, când throwo eroare, puteți face acest lucru cu throw new CustomError("Something went wrong..."). De asemenea, vă oferă posibilitatea de a verifica erorile împotriva tipului:

try { throw new CustomError("Something went wrong")} catch (error) { if (error instance of CustomError) { // do something specifically for that type of error }}

acest singur nu face mult, altele decât vă dau un nou tip de eroare pentru a apela și a verifica pentru. Pentru a înțelege mai bine ce se poate face, să ne uităm la ceea ce vine standard pe Error.

  • Error.name
  • Eroare.mesaj
  • eroare.prototip.toString ()
  • greșit.prototip.constructor()

nu de mult pentru a lucra cu este acolo? În afară de constructor și metoda toString, numele erorii și mesajul care descrie eroarea sunt singurele părți pe care este posibil să le folosim. În exemplul de mai sus, message este setat prin trecerea „ceva nu a mers bine” ca argument la instanțierea erorii.

din fericire, majoritatea platformelor javascript precum browserul și nodul.js și-au adăugat propriile metode și proprietăți pe lângă cele enumerate. Ne vom concentra pe câteva aspecte ale implementării erorilor de la V8, motorul Javascript care alimentează Chrome și Node.js.

cele două domenii de interes sunt stackși captureStackTrace. După cum sugerează și numele lor, acestea vă permit să ieșiți la suprafață. Să vedem cum arată asta cu un exemplu.

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)}

în acest exemplu sunăm Error.captureStackTrace, dacă platforma o acceptă, pentru a ne asigura că se adaugă o urmă completă la eroarea noastră personalizată. Apoi throw eroarea din interiorul blocului try, care va trece controlul la blocul catch.

dacă executați codul de mai sus, veți vedea că prima linie a stack este eroarea nameși message.

Our Custom Error: Something went wrong

această eroare nu este foarte „profundă”, deci stiva este în mare parte nod.JS interne. Fiecare linie este un” cadru ” al stivei. Acestea conțin detalii despre locația erorii în baza de cod.

acum, că știm cum să facem și să apelăm la o eroare personalizată, să o facem utilă.

personalizarea conținutului de eroare

eroarea personalizată cu care am lucrat este în regulă, dar să o schimbăm pentru a o face mai utilă. Clasa va fi CircuitError. Îl vom folosi pentru a furniza erori personalizate provenite de la un întrerupător de circuit. Dacă nu sunteți familiarizați cu modelul, este în regulă. Detaliile de implementare ale întrerupătorului nu sunt importante. Ceea ce este important este că putem transmite unele informații în eroare și va prezenta aceste informații utilizatorului.

un întrerupător are o stare „deschisă” care nu permite nimic să treacă prin el pentru o perioadă fixă de timp. Să setăm CircuitError pentru a conține câteva detalii care ar putea fi utile funcțiilor care o primesc atunci când starea este 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.` } }}

eroarea noastră actualizată face câteva lucruri noi, toate în cadrul constructorului. Argumentele transmise s-au schimbat (1) pentru a include state a întrerupătorului, precum și un marcaj de timp nextAttempt pentru a indica când întrerupătorul va începe să încerce din nou cererile.

apoi setează câteva proprietăți noi și actualizează mesajul în funcție de valorile prezentate. Îl putem testa aruncând o nouă versiune a acestei erori.

try { throw new CircuitError("OPEN", Date.now() + 8000)} catch (err) { console.error(err)}

acum, când aruncăm eroarea, este nevoie de stat ca primul argument și un marcaj de timp ca al doilea. Pentru acest demo vom trece în timp 8000 milisecunde în viitor. Observați că suntem, de asemenea, de logare eroarea în sine, mai degrabă decât doar stiva.

rularea codului va avea ca rezultat ceva de genul următor:

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}

rezultatul este numele erorii urmat de mesajul de pe prima linie. Apoi avem restul stivei, urmat de toate proprietățile pe care le-am stabilit în CircuitError. Consumatorii noștri de această eroare ar putea folosi aceste date pentru a reacționa la eroare. De exemplu:

try { throw new CircuitError("OPEN", Date.now() + 8000)} catch (err) { customLogger(err) if (err.state === "OPEN") { handleOpenState(err.nextAttempt) }}

în loc de o eroare generică, acum avem ceva mai potrivit pentru nevoile aplicației noastre.

reacționând la eșecuri

Erorile personalizate sunt o modalitate excelentă de a reacționa la eșecuri. Este obișnuit să presupunem că toate erorile sunt neașteptate, dar oferind erori utile puteți face existența lor mai ușor de manevrat. Folosind erori personalizate, nu numai că putem oferi utilizatorilor aplicațiilor noastre date valoroase, dar prezentăm și capacitatea de a răspunde tipurilor de erori prin condiția instance of.

la purtător, folosim erori personalizate pentru a standardiza răspunsurile în codul nostru, pentru a furniza doar informațiile de care aveți nevoie în clientul nostru și pentru a face erorile noastre acționabile.

cum utilizați erori personalizate în aplicațiile dvs.? Conectează-te cu noi @BearerSH și să ne anunțați.

Lasă un răspuns

Adresa ta de email nu va fi publicată.