Welcome to Our Website

erori personalizate, eroare de extindere

când dezvoltăm ceva, avem adesea nevoie de propriile noastre clase de eroare pentru a reflecta lucruri specifice care pot merge prost în sarcinile noastre. Pentru erori în operațiunile de rețea poate avem nevoie de HttpError, pentru operațiuni de baze de date DbError, pentru căutarea operațiunilor NotFoundError și așa mai departe.

erorile Noastre ar trebui să sprijine eroare de bază de proprietăți, cum ar fi message, name și, de preferință, stack. Dar ele pot avea și alte proprietăți proprii, de ex., HttpError obiecte pot avea un statusCode proprietate cu o valoare ca 404 sau 403 sau 500.

JavaScript vă permite să utilizați throw cu orice argument, atât din punct de vedere tehnic nostru de eroare personalizate clase nu trebuie să moștenesc de la Error. Dar dacă moștenim, atunci devine posibil să folosim obj instanceof Error pentru a identifica obiectele de eroare. Deci este mai bine să moștenești de la ea.pe măsură ce aplicația crește, propriile noastre erori formează în mod natural o ierarhie., De exemplu, HttpTimeoutError poate moșteni de la HttpError, și așa mai departe.

eroare de extindere

ca exemplu, să luăm în considerare o funcție readUser(json) care ar trebui să citească JSON cu datele utilizatorului.

Aici e un exemplu de cum un valabile json poate arata:

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

pe plan Intern, vom folosi JSON.parse. Dacă primește malformat json, atunci aruncă SyntaxError., Dar chiar dacă json este corect din punct de vedere sintactic, asta nu înseamnă că este un utilizator valid, nu? Este posibil să pierdeți datele necesare. De exemplu, este posibil să nu fi name și age proprietăți care sunt esențiale pentru utilizatorii noștri.

funcția noastră readUser(json) nu va citi doar JSON, ci va verifica („valida”) datele. Dacă nu există câmpuri obligatorii sau dacă Formatul este greșit, atunci aceasta este o eroare. Și nu este un SyntaxError, deoarece datele sunt corecte din punct de vedere sintactic, ci un alt tip de eroare., O vom numi ValidationError și vom crea o clasă pentru aceasta. O eroare de acest fel ar trebui să conțină, de asemenea, informațiile despre câmpul ofensator.

ValidationError clasa ar trebui să moștenească de la built-in Error clasa.

clasa este construit-in, dar aici e aproximativă de cod astfel încât să putem înțelege ce ne extinde:

Acum, haideți să moștenească ValidationError de la ea și încercați să-l în acțiune:

vă Rugăm să rețineți: în linia (1) noi numim părintele constructor., JavaScript ne cere să apelăm super în constructorul copilului, deci este obligatoriu. Constructorul părinte stabilește message proprietate.

– mamă constructorul stabilește, de asemenea, name proprietatea de a "Error", astfel încât în linie (2) am a-l reseta la valoarea de dreapta.,

Să încercăm să-l folosească în readUser(json):

try..catch bloc în codul de mai sus se ocupă de ambele noastre ValidationError și-a construit în SyntaxError de la JSON.parse.

vă rugăm să aruncați o privire la modul în care folosim instanceof pentru a verifica tipul de eroare specific în linia (*).,

Am putea, de asemenea, uita-te la err.name, astfel:

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

instanceof versiune este mult mai bine, pentru că în viitor vom extinde ValidationError, face subtipuri de ea, ca PropertyRequiredError. Șiinstanceof verificarea va continua să funcționeze pentru noi clase de moștenire. Deci, asta e viitor-dovada.

de Asemenea, este important că, dacă catch întâlnește o eroare necunoscută, apoi rethrows în linie (**)., Blocul catch știe doar cum să gestioneze erorile de validare și sintaxă, alte tipuri (din cauza unei greșeli în cod sau a altor necunoscute) ar trebui să cadă.

moștenire suplimentară

clasaValidationError este foarte generică. Multe lucruri pot merge prost. Proprietatea poate fi absentă sau poate fi într-un format greșit (cum ar fi o valoare șir pentru age). Să facem o clasă mai concretă PropertyRequiredError, exact pentru proprietățile absente. Acesta va transporta informații suplimentare despre proprietatea care lipsește.,

noua clasă PropertyRequiredError este ușor de utilizat: trebuie doar să-și treacă numele proprietății: new PropertyRequiredError(property). Citibilul uman message este generat de constructor.

vă Rugăm să rețineți că this.name în PropertyRequiredError constructor este din nou atribuită manual. Acest lucru poate deveni un pic obositor – pentru a atribui this.name = <class name> în fiecare clasă de eroare personalizată. O putem evita făcând propria noastră clasă „eroare de bază”care atribuie this.name = this.constructor.name. Și apoi moștenim toate erorile noastre personalizate din ea.,

să-l numim MyError.

Aici este codul cu MyError și alte personalizat eroare clase, simplificată:

Acum personalizat erorile sunt mult mai scurte, mai ales ValidationError, ca am scapat de "this.name = ..." linie în constructor.

excepții de împachetare

Scopul funcțieireadUser în codul de mai sus este „citirea datelor Utilizatorului”. Pot apărea diferite tipuri de erori în acest proces., Acum avem SyntaxError și ValidationError, dar în viitor readUser funcție poate să crească și, probabil, de a genera alte tipuri de erori.

codul care apelează readUser ar trebui să gestioneze aceste erori. Acum se folosește multiple ifîn catch bloc, care verifica clasă și să se ocupe de erori cunoscute și rethrow necunoscut altele.

schema este astfel:

în codul de mai sus putem vedea două tipuri de erori, dar pot exista mai multe.,dacă funcția readUser generează mai multe tipuri de erori, atunci ar trebui să ne întrebăm: chiar vrem să verificăm toate tipurile de erori unul câte unul de fiecare dată?adesea răspunsul este „nu”: ne-ar plăcea să fim”cu un nivel mai presus de toate”. Vrem doar să știm dacă a existat o „eroare de citire a datelor” – de ce sa întâmplat exact este adesea irelevant (mesajul de eroare îl descrie). Sau, chiar mai bine, am dori să avem o modalitate de a obține detaliile erorii, dar numai dacă este necesar.tehnica pe care o descriem aici se numește „excepții de împachetare”.,

  1. vom face o nouă clasă ReadError pentru a reprezenta o eroare generică „citirea datelor”.
  2. funcția readUser va prinde citirea datelor erorile care apar în interiorul acestuia, cum ar fi ValidationError și SyntaxError, și pentru a genera un ReadError în loc.
  3. ReadError obiect va păstra referire la eroarea inițială în cause proprietate.,apoi, codul care apelează readUser va trebui să verifice doar ReadError, nu pentru orice fel de erori de citire a datelor. Și dacă are nevoie de mai multe detalii despre o eroare, poate verifica proprietatea cause.,

    Aici e codul care definește ReadError și demonstrează utilizarea acestuia în readUser și try..catch:

    În codul de mai sus, readUser funcționează exact așa cum a descris – capturile de sintaxă și erori de validare și aruncă ReadError erori (erori necunoscute sunt rethrown ca de obicei).

    deci codul exterior verifică instanceof ReadError și asta este. Nu este nevoie să enumerați toate tipurile de erori posibile.,

    abordarea se numește „excepții de împachetare”, deoarece luăm excepții de” nivel scăzut „și le” înfășurăm”în ReadError care este mai abstract. Este utilizat pe scară largă în programarea orientată pe obiecte.

    rezumat

    • putem moșteni de la Error și alte clase de eroare încorporate în mod normal. Trebuie doar să avem grijă de proprietatea name și nu uitați să apelați super.
    • putem folosi instanceof pentru a verifica anumite erori. De asemenea, funcționează cu moștenire., Dar, uneori, avem un obiect de eroare provenind dintr-o bibliotecă 3rd-party și nu există nici o modalitate ușoară de a obține clasa sa. Apoi name proprietatea poate fi utilizată pentru astfel de verificări.
    • excepțiile de împachetare sunt o tehnică larg răspândită: o funcție gestionează excepțiile de nivel scăzut și creează erori de nivel superior în loc de diferite cele de nivel scăzut. Excepțiile de nivel scăzut devin uneori proprietăți ale acelui obiect, cum ar fi err.cause în exemplele de mai sus, dar acest lucru nu este strict necesar.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *