0

While going through the Angular tutorial and converting it to my purposes, I decided that I want to combine the 2 varieties of error handler method shown into one, because i like the function of both.

This is all in one service, and these are the 2 methods from the tutorial:

  private handleError1(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      console.error('An error occurred', error.error.message);
    } else {
      console.error(`Backend error code ${error.status}`, 
        `body: ${error.error}`);
    }
    return throwError('Something bad happened');
  }

which is called like this, where Group is my class from the REST server:

  getGroups(): Observable<Group[]> {
    return this.httpClient.get<Group[]>(`${this.restUrl}/group`).pipe(
        tap(_ => this.log(`fetched groups`)),
        catchError(this.handleError1)
      );
  }

and then alternatively, there is:

  private handleError2<T>(operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {
      console.error(`${operation} failed!`, error);
      return of(result as T);
    }
  }

which is called like this:

  getGroups(): Observable<Group[]> {
    return this.httpClient.get<Group[]>(`${this.restUrl}/group`).pipe(
        tap(_ => this.log(`fetched groups`)),
        catchError(this.handleError2<Group[]>('getGroups', []))
      );
  }

So I naively put together my combination error handler:

private handleError<T>(error: HttpErrorResponse, 
                   operation = 'operation', result?: T) {
....

but I am having problems because I can't figure out how to parameterise it within catchError(). That HttpErrorResponse is obviously implied somehow when it's the only parameter, but how?

1 Answer 1

1

I spent a bit more time on this.

First, I ensured I had a recent version of TypeScript. My project is using 3.1.1.

This is my method:

  getProducts(): Observable<Product[]> {
    return this.http.get<Product[]>(this.productUrl).pipe(
      tap(data => console.log('All: ' + JSON.stringify(data))),
      catchError(error => this.handleError<Product[]>(error, 'get', [] ))
    );
  }

This is my error handler:

  private handleError<T>(err: HttpErrorResponse, operation = 'operation', result?: T) {
    // in a real world app, we may send the server to some remote logging infrastructure
    // instead of just logging it to the console
    let errorMessage = '';
    if (err.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      errorMessage = `An error occurred: ${err.error.message}`;
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      errorMessage = `Server returned code: ${err.status}, error message is: ${err.message}`;
    }
    console.error(errorMessage);
    return throwError(errorMessage);
  }

I'm not getting any compilation errors with this code.

I even turned on strict mode in my tsconfig.json:

"strict": true,

And it still compiled without syntax errors.

I built a stackblitz here: https://stackblitz.com/edit/angular-simple-retrieve-deborahk

Let me know if you aren't seeing the same result.

Sign up to request clarification or add additional context in comments.

5 Comments

I get a big dirty compilation error from IntelliJ saying Error:(62, 13) TS2345: Argument of type '(error: any) => (error: any) => Observable<Group[]>' is not assignable to parameter of type '(err: any, caught: Observable<Group[]>) => ObservableInput<{}>'. Type '(error: any) => Observable<Group[]>' is not assignable to type 'ObservableInput<{}>'. Property '[Symbol.iterator]' is missing in type '(error: any) => Observable<Group[]>' but required in type 'Iterable<{}>'.
Hmmm. I tried it in my code before posting and it worked. Do you have strict type checking on? Or other code you are not showing above?
That's the defaults. Both the IntelliJ built-in compiler and the external node.js when I run ng serve --open
What version of TypeScript are you running? Is your code basically the same as mine?
3.3.3. I just upgraded it from 3.2.4. But I narrowed the issue down to a weird syntax I had used in my return statement for handleError(), and now it's happy! Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.