false

Exceptions in Angular

Exceptions sind Ereignisse, die während der Ausführung eines Programms auftreten und die normalen Abläufe unterbrechen. Sie signalisieren, dass ein Fehler aufgetreten ist, der das Programm nicht ohne Weiteres fortführen kann. Exceptions können durch unerwartete Eingabedaten, Fehler im Programmcode oder Ausnahmebedingungen verursacht werden.

Exceptions können behandelt werden, indem ein Exception-Handler verwendet wird. Der Exception-Handler kann dann entsprechend reagieren, indem er beispielsweise eine Fehlermeldung ausgibt, das Programm beendet oder versucht, den Fehler zu beheben und das Programm fortzuführen.

In Angular und anderen Programmiersprachen gibt es sowohl die Möglichkeit einen globalen Error-Handler zu definieren, der für alle Fehler angewendet wird, aber auch die Möglichkeit einen Error-Handler nur auf bestimmte Methoden oder Funktionen anzuwenden.

Es gibt auch unterschiedliche Arten von Exceptions, einige davon sind:

  • Checked Exceptions: diese sind die Exceptions, die explizit im Code behandelt werden müssen, z.B. durch eine try-catch-Anweisung.
  • Unchecked Exceptions: Diese sind die Exceptions, die nicht explizit im Code behandelt werden müssen, z.B. die Exceptions die von der Java Virtual Machine (JVM) geworfen werden.
  • Errors: Errors sind schwerere Fehler als Exceptions, die in der Regel nicht behandelt werden können und die das Programm nicht fortführen kann.

Es ist wichtig, dass man Exceptions nicht ignorieren sollte und sie behandelt, um die Stabilität und Sicherheit des Programms sicherzustellen.

Um einen Exception-Handler in Angular zu erstellen, kannst Du die Klasse ErrorHandler von Angular verwenden. Zudem kannst Du eine Subklasse von ErrorHandler erstellen und die Methode handleError überschreiben, um benutzerdefinierte Fehlerbehandlungslogik hinzuzufügen.

import { ErrorHandler } from '@angular/core';

export class MyErrorHandler implements ErrorHandler {
  handleError(error: any): void {
    // Hier kannst Du deinen benutzerdefinierte Fehlerbehandlungslogik hinzufügen.
    console.error(error);
  }
}

Um Deinen benutzerdefinierten ErrorHandler zu verwenden, musst Du ihn in der @NgModule-Deklaration als provider hinzufügen:

import { MyErrorHandler } from './my-error-handler';

@NgModule({
  providers: [{ provide: ErrorHandler, useClass: MyErrorHandler }]
})
export class AppModule {}

Jetzt wird jeder Fehler, der innerhalb Ihrer Anwendung auftritt, durch Deine benutzerdefinierte Fehlerbehandlungslogik behandelt.

Die meisten Fehler treten in der Kummunikation von Schnittstellen auf. Hierzu möchte ich mir mit dir zusammen einen benutzerdefinierten Exception-Handler für den HttpClient von Angular anschauen.

In diesem Beispiel greifen wir einen HTTP-Fehler von einem GET-Request mit dem Angular HttpClient ab:

import { ErrorHandler, Injectable } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class MyErrorHandler implements ErrorHandler {
  constructor(private http: HttpClient) {}

  handleError(error: any): void {
    if (error instanceof HttpErrorResponse) {
      if (error.status === 400) {
        console.error('Bad Request');
      } else {
        console.error('An error occurred:', error.error);
      }
    }
  }
}

@Injectable()
export class MyService {
  constructor(private http: HttpClient) {}

  getData(): Observable<any> {
    return this.http.get<any>('https://my-api.com/data').pipe(
      catchError((error: HttpErrorResponse) => {
        throw error;
      })
    );
  }
}

Hier wird eine eigene Klasse MyErrorHandler implementiert, die von ErrorHandler erbt und die Methode handleError überschreibt. In der Methode handleError wird überprüft, ob der Fehler eine Instanz von HttpErrorResponse ist. Wenn ja, wird überprüft, ob der Fehlerstatus 400 ist. Wenn ja, wird eine Fehlermeldung auf der Konsole ausgegeben.

In der Klasse MyService wird der HttpClient verwendet, um einen GET-Request an eine API zu senden. Der catchError-Operator wird verwendet, um jeden Fehler, der von der API zurückgegeben wird, abzufangen und an den benutzerdefinierten Exception-Handler weiterzuleiten.

Hier müssen wir beachten, dass dieser ErrorHandler nur für diese Methode gilt. Wenn wir unseren benutzerdefinierten ErrorHandler Global, also unabhängig davon, in welchem Modul oder welcher Komponente sie auftreten, verwenden möchten, müssen wir ihn in der @NgModule-Deklaration als Provider hinzufügen wie folgt:

import { MyErrorHandler } from './my-error-handler';

@NgModule({
  providers: [{ provide: ErrorHandler, useClass: MyErrorHandler }]
})
export class AppModule {}

Wenn Wir nun die Anwendung starten, wird Angular den benutzerdefinierten ErrorHandler verwenden, um Fehler zu behandeln, die innerhalb der gesamten Anwendung auftreten.

Hier ist noch ein Beispiel für ein handleError für HTTP-Requests:

handleError(error: Error | HttpErrorResponse) {
    if (error instanceof HttpErrorResponse) {
      switch (error.status) {
        case 400:
          console.error('Bad Request');
          break;
        case 500:
          console.error('Internal Server Error');
          break;
        default:
          console.error('An error occurred:', error.error);
          break;
      }
    } else {
      console.error('An error occurred:', error.message);
    }
  }

In diesem Beispiel wird zunächst wieder überprüft, ob der Fehler eine Instanz von HttpErrorResponse ist. Wenn ja, wird der Fehlerstatus mit einer switch-Anweisung überprüft. Jeder Fall (case) entspricht einem bestimmten Fehlerstatus und die entsprechende Fehlermeldung wird auf der Konsole ausgegeben.

Der break-Befehl in jedem Fall sorgt dafür, dass die Ausführung nach dem entsprechenden Fall beendet wird und nicht in die nächste Anweisung übergeht.

Es ist wichtig darauf zu achten, dass es auch einen default case gibt, damit auch unbekannte Fehler behandelt werden können.

Ich hoffe ich konnte dir zum Thema Exception Handling in Angular einen guten Einblick vermitteln!