GEDOPLAN
Webprogrammierung

Angular, HTTP Error Handler

Webprogrammierung

Eine Rest-Schnittstelle über den von Angular bereitgestellten HTTP-Service an zu binden ist nicht schwer. Dank Observables ist auch die Fehlerbehandlung kein großer Aufwand. Trotzdem muss diese Behandlung für jede Kommunikation deklariert werden was zu lästigem Schreibaufwand führt und die Anwendung auch unübersichtlich macht. Wie sieht eine Möglichkeit aus, generisch auf HTTP Fehler zu reagieren, ohne diese Behandlung bei jedem Aufruf zu implementieren? Werfen wir einen Blick darauf.

app

Um zum Beispiel mit Rest-Schnittstellen zu kommunizieren verwenden wir in Angular den bereitgestellten HTTP Service der uns diverse Methoden zur Verfügung stellt die verschiedenen Request-Typen zu verwenden. Ein einfache Beispiel und dessen Verwendung könnte so aussehen:

jsonplace-holder.service.ts

@Injectable()
export class JSONPlaceHolderService {

  constructor(private http: Http, @Inject(SERVICE_BASE_URL) private baseurl:string) { }

  ladeUserDaten(userId: number): Observable<any> {
    return this.http.get( this.baseurl + 'users/' + userId).map(r => r.json());
  }

}

app.component.ts

  ladeDaten() {
    this.service.ladeUserDaten(5).subscribe(
      u => this.userDaten = u,
      error => console.log('Fehler: ' + error)
   );
  }

(die Fehlerbehandlung durch eine Konsolen-Ausgabe zu implementieren ist natürlich keine gute Idee. In aller Regel werden wir einen zentralen Service verwenden der sich darum kümmert das die Ausgaben an den Benutzer weiter gegeben werden)

Die Behandlung der Fehler, egal in welcher Form sie nun implementiert ist, müsste nun bei jedem Methodenaufruf verwendet werden. Selbst dann wenn wir lediglich eine ganze allgmeine Meldung ausgeben wollen.

Die eigene ‘http’ Implementierung

Der Titel klingt umfassender als es wirklich ist. Eigentlich erweitern wir den bestehenden HTTP-Service lediglich um eine einheitliche Fehlerbehandlung.

Dazu überschreiben wir die Request-Methode, leiten den eigentlichen Aufruf an die originale Implementierung weiter und registrieren eine Methode (“catch”) die sich um unsere Fehlerbehandlung kümmern soll. In diesem Fall leitet der HTTP-Interceptor diese Fehlermeldung an einen separaten Service weiter um den User diese Information an zu zeigen.

jsonplace-holder.service.ts

// operators
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/map';

@Injectable()
export class HttpInterceptor extends Http {

    constructor(backend: XHRBackend,options: RequestOptions, private errorService:ErrorHandleService) {
        super(backend, options)
    }

    public request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
        return super.request(url, options)
            .catch(this.handleError)
    }

    public handleError = (error: Response) => {
        this.errorService.addError(error.toString());
        return Observable.throw(error)
    }
}

Soweit so gut. Nun müssen wir lediglich dafür Sorge tragen das bei der Injizierung des HTTP-Services (wie oben zu sehen) unsere eigene Implementierung herangezogen wird und nicht die von Angular selbst. Dazu implementieren wir einen entsprechenden Provider in unserem Modul. Dieser Provider ist hier im Beispiel eine Factory-Methode, damit wir andere Services die ebenfalls per Depedency Injektion bereit gestellt werden an unsere Implementierung übergeben können:

app.module.ts

  providers: [
   ...
    ErrorHandleService,
    {
      provide: Http,
      deps: [XHRBackend, RequestOptions, ErrorHandleService],
      useFactory: (backend: XHRBackend, defaultOptions: RequestOptions, service: ErrorHandleService) => new HttpInterceptor(backend, defaultOptions, service)
    }
  ],

Nachricht an den User

Zur Vollständigkeit noch eine kurze Zusammenfassung wie die Benachrichtigung an den Benutzer erfolgt. Wie oben zu sehen verwenden wir einen Service der die Fehler entgegen nimmt. Dieser Service ist sehr überschaubar und hält lediglich ein “Subject” (rxjs-Packet) bereit an dem sich andere Komponenten registrieren können. In unserem Mini-Beispiel erfolgt die Registrierung direkt in der Hauptkomponenten die bei neuen Nachrichten diese in einer Variablen ablegt, auf dessen Basis eine Meldung im Frontend angezeigt wird. Zusätzlich blenden wir die entsprechenden Fehlermeldungen noch nach einigen Sekunden aus.

error-handler.service.ts

@Injectable()
export class ErrorHandleService {

  public messages = new Subject<string>();

  addError(error: string) {
    this.messages.next(error);
    throw error;
  }
}

app.component.ts

    errorService.messages.subscribe(e => {
      this.globalErrorMessage = e;
      setTimeout(() => this.globalErrorMessage = null, 5000);
    });

app.component.html

<div *ngIf="globalErrorMessage">
<div class="alert alert-danger">
            {{globalErrorMessage}}</div>
</div>

 

Wie immer. Alles. Live. In Farbe. Bei Github

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Bitte füllen Sie dieses Feld aus.
Bitte füllen Sie dieses Feld aus.
Bitte gib eine gültige E-Mail-Adresse ein.
Sie müssen den Bedingungen zustimmen, um fortzufahren.

Autor

Diesen Artikel teilen

LinkedIn
Xing

Gibt es noch Fragen?

Fragen beantworten wir sehr gerne! Schreibe uns einfach per Kontaktformular.

Kurse

weitere Blogbeiträge

mask g258b04055 640
Web Security, Jakarta EE (Java EE), Spring

Jackson JSON Filter

JSON als Datenstruktur ist bei der Implementierung von Webservices kaum wegzudenken. Insbesondere Jackson als JSON Parser bietet eine ganze Reihe von Möglichkeiten, um auf die Generierung einzuwirken. Ein naheliegen Anwendungsfall hier z.B. das Ausblenden von bestimmten Attributen basierend auf Benutzer-Rollen oder Berechtigungen. Vorhang auf für: @JsonFilter

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!