Как выполнить ErrorHandling с помощью оператора catchError Rx JS в Angular? - PullRequest
0 голосов
/ 18 июня 2020

Я новичок в Angular / Typescript и использую catchError Rx Js. Я также использую операторы .subscribe и pipe. Я хотел бы как можно больше использовать наблюдаемое, комбинируя его с операторами Rx JS. При отправке моей формы интерфейс вызывает API, и создается новый продукт, который хотел бы иметь правильную обработку ошибок для кодов ошибок 400 и 500 с использованием HttpErrorResponse. Я написал код ниже, но не уверен, правильно ли я обрабатываю ошибки, поскольку получаю ошибку ниже (см. Внизу).

app.component.ts

onSubmit(): void {
    if (this.form.valid) {
        console.log('Creating product:', this.form.value);
        this.http.post('/api/create', {
            productName: this.form.value.productName,
        }).pipe(catchError(err => {
            if(err instanceof HttpErrorResponse && err.status == 500 || err.status == 502 || err.status == 503) {
                this.err = "Server Side Error";
                return throwError(err);;
            }
            else if(err instanceof HttpErrorResponse && err.status == 400){
                this.err = "Bad Request";
                return throwError(err);;
            } else if(err instanceof HttpErrorResponse && err.status == 422){
                this.err = "Unprocessable Entity - Invalid Parameters";
                return throwError(err);;
            }
        })
          .subscribe(
            resp => this.onSubmitSuccess(resp), err => this.onSubmitFailure(err)
        );
    }
    this.formSubmitAttempt = true;
}

private onSubmitSuccess(resp) {
    console.log('HTTP response', resp);
    this.productID = resp.projectID;
    this.submitSuccess = true;
    this.submitFailed = false;
}

private onSubmitFailure(err) {
    console.log('HTTP Error', err);
    this.submitFailed = true;
    this.submitSuccess = false;
}

Ошибки:

app.component.ts - ошибка TS2339: свойство 'err' не существует для типа «AppComponent».

app.component.ts: 124: 16 - ошибка TS2339: свойство «subscribe» не существует для типа «OperatorFunction».}). subscribe (

1 Ответ

1 голос
/ 18 июня 2020

Чтобы решить вашу проблему, я изменил код, показанный ниже.


      onSubmit(): void {
    if (this.form.valid) {
        console.log('Creating product:', this.form.value);
        this.http.post('/api/create', {
            productName: this.form.value.productName,
        }).pipe(catchError(errorResponse=> {

        const err = <HttpErrorResponse>errorResponse;

        if (err && err.status === 422) {
           this.err = "Unprocessable Entity - Invalid Parameters";
                return throwError(err);            
        } else if (err && err.status === 400) {
                this.err = "Bad Request";
                return throwError(err);;      
        } else if (err && err.status === 404) {
          this.err = "Not found";
                return throwError(err);;    
        } else if (
          err &&
          (err.status < 200 || err.status <= 300 || err.status >= 500)
        ) {
            this.err = "Server Side Error";
                return throwError(err);;
        }
        })
          .subscribe(
            resp => this.onSubmitSuccess(resp), err => this.onSubmitFailure(err)
        );
    }
    this.formSubmitAttempt = true;
}

Я бы предложил создать общую службу исключений, которая обрабатывает любые исключения. Вы должны разделить исходящие вызовы API на отдельную службу, а затем использовать ее в своем компоненте. Код будет легко читать и поддерживать. Попробуйте следующий код logi c.

import { HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';

@Injectable()
export class ExceptionService {
  constructor(private toastService: ToastService) {}

  catchBadResponse: (errorResponse: any) => Observable<any> = (
    errorResponse: any
  ) => {
    let res = <HttpErrorResponse>errorResponse;
    let err = res;
    let emsg = err
      ? err.error
        ? err.error
        : JSON.stringify(err)
      : res.statusText || 'unknown error';
console.log(`Error - Bad Response - ${emsg}`);
    return of(false);
  };
}

В своей службе вы можете создать такой метод публикации

saveEntity(entityToSave: EntityToSave) {
    return <Observable<EntityToSave>>(
      this.http.post(`${postURL}`, entityToSave).pipe(
        map((res: any) => <EntityToSave>res),
        catchError(this.exceptionService.catchBadResponse),
        finalize(() => console.log('done'))
      )
    );
  }

Из вашего компонента вызовите службу, которая обрабатывает исключение

   this.yourService.saveEntity(entityToSave).subscribe(s => {
       //do your work... this get called when the post call was successfull
      });

Надеюсь, это решит вашу проблему.

...