ProgrammierungBackend-Entwickler

Beschreiben Sie, wie der Mechanismus der benutzerdefinierten Fehler (Custom Errors) in TypeScript funktioniert. Wie sollten benutzerdefinierte Fehlerklassen korrekt deklariert werden, warum sollten ihre Typen angegeben werden und wie kann man Fallen mit 'instanceof' und der Serialisierung von Fehlern vermeiden?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

Hintergrund: In JavaScript werden Standardfehler durch die Klasse Error beschrieben. In großen TypeScript-Projekten ist es wichtig, eine eigene Fehlerhierarchie für eine präzise Verarbeitung von Situationen zu verwenden, jedoch gibt es Nuancen in Bezug auf Typen, Vererbung und das Verhalten von 'instanceof'.

Problem: Bei der Vererbung von Error können Schwierigkeiten auftreten: das Prototyp wird verloren, 'instanceof' funktioniert nicht richtig, Typen können inkorrekt beschrieben sein und die Serialisierung führt oft zum Verlust des Stack-Trace. Ohne explizite Angabe der Eigenschaften können Bugs bei der Fehlerverarbeitung entstehen.

Lösung: Benutzerdefinierte Fehler sollten korrekt durch Erweiterung der Klasse Error definiert werden. Es ist wichtig, den Namen explizit anzugeben, den Prototyp manuell wiederherzustellen (wichtig für ES5 und bei der Kompilierung in CommonJS) und die Feldtypen der Fehler zu definieren.

Codebeispiel:

class ValidationError extends Error { code: number; constructor(message: string, code: number = 400) { super(message); Object.setPrototypeOf(this, ValidationError.prototype); this.name = 'ValidationError'; this.code = code; } } function process(user: string) { if (!user) throw new ValidationError('User required', 401); }

Schlüsselfunktionen:

  • Explizite Wiederherstellung des Prototyps zur Unterstützung von 'instanceof' selbst bei Transpilation.
  • Typisierung benutzerdefinierter Eigenschaften von Fehlern.
  • Individuelle Klasse für jede logische Fehlergruppe.

Fragen mit Fallen.

Warum kann der Aufruf von Object.setPrototypeOf(this, ...) nicht weggelassen werden?

Wenn Object.setPrototypeOf(this, Class.prototype) nicht aufgerufen wird, funktioniert 'instanceof' ValidationError nicht bei der Kompilierung in ES5/CommonJS oder Babel. Dies führt dazu, dass die catch-Blöcke von ValidationError den Fehler nicht abfangen.

class CustomErr extends Error {} const err = new CustomErr('msg'); console.log(err instanceof CustomErr); // false ohne setPrototypeOf

Kann das Feld name bei benutzerdefinierten Fehlern weggelassen werden?

Wenn das this.name nicht gesetzt wird, sind der Fehlerstack und die Anzeige in Logs inkorrekt, was die Ursachenforschung und Kategorisierung von Fehlern erschwert.

Müssen Fehler serialisierbar sein und wenn ja, wie?

Fehler sollten korrekt serialisiert werden (z. B. für Logging oder Übertragung über das Netzwerk), sonst gibt JSON.stringify(new Error()) keine message und stack aus. Es sollte die Methode toJSON überschrieben werden.

class SerializableError extends Error { toJSON() { return { name: this.name, message: this.message, stack: this.stack }; } }

Typische Fehler und Anti-Pattern

  • Fehlen von Object.setPrototypeOf führt zu falscher Funktionsweise von instanceof
  • Ignorieren von name und benutzerdefinierten Eigenschaften
  • Serialisierung von Fehlern ohne Implementierung von toJSON: Verlust von stack/message

Beispiel aus der Praxis

Negativer Fall

Im Projekt wurde einfach class MyError extends Error erstellt, wobei der Prototyp nicht wiederhergestellt wurde. Fehler wurden über if (err instanceof MyError) abgefangen, aber das funktionierte nicht, und der Code ignorierte stillschweigend die Behandlung kritischer Situationen.

Vorteile:

  • Der Code sah kompakt aus
  • Kein Boilerplate

Nachteile:

  • instanceof funktionierte nicht
  • Ausnahmen wurden nicht korrekt geloggt
  • Bei der Änderung des ts->js Transpilers trat Inkompatibilität auf

Positiver Fall

Ein korrekter CustomError wurde implementiert, name, code und toJSON wurden explizit festgelegt, Tests deckten die Verarbeitung verschiedener Fehlerarten ab. In Logs und in den catch-Handlern wurde die Struktur der Fehler klarer, wodurch die Fehlersuche beschleunigt wurde.

Vorteile:

  • Klare Typenhierarchie der Fehler
  • Zuverlässige Serialisierung
  • Plattformübergreifende Kompatibilität zwischen Browser und Node.js

Nachteile:

  • Es gab eine wiederholende Logik in jeder CustomError-Klasse