title: How to catch error response properly in Angular?
body: <p>i need to catch response body produced by my REST API, which is throwing http error 406 with custom response body, but in my angular, i only can catch the header status which is 'Not Acceptable', i can't get the body, how can i get the body instead of the 'Not Acceptable' string? and i got this error too <code>TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.</code> which is i dunno which part that trigger this error. Here is how i do it :</p>
  <p>first i create global service class, which is looked like this :</p>
  <pre><code>  constructor(
      private http: HttpClient,
      private alertx: AlertService) { }
  
      post&lt;T&gt;(url: string, body?: any, header?: HttpHeaders, param?: HttpParams): Observable&lt;HttpResponse&lt;T&gt;&gt;{
        return this.http.post&lt;T&gt;(url, body,
          {headers : header ? header : this.headers,
          observe: 'response',
          responseType: 'json',
          params: param})
          .pipe(catchError(err =&gt; {
            const error = err.error?.error_description || err.error?.message || err.statusText;
            console.log(err);
            console.log('here i am');
            return throwError(error);
          }))
          .pipe(timeout(10000), catchError(err =&gt; {
            if (err instanceof TimeoutError) {
              this.alertx.error('Timeout Exception');
              return throwError('Timeout Exception');
            }
          }))
          .pipe(shareReplay());
    }
  </code></pre>
  <p>i tried to console.log the error it just appear string 'Not Acceptable', and it continued by console.log('here i am'); it print out properly, and i can't find where the cause of <code>TypeError</code></p>
  <p>here is how i use function above :</p>
  <pre><code>  requestCancel(data: SelectItem, reasonCancel: string): Observable&lt;any&gt; {
        const request: RequestResponse&lt;SelectItem&gt; = new RequestResponse&lt;SelectItem&gt;(data);
        request.message = reasonCancel;
        return this.rest.post&lt;any&gt;(`${environment.apiUrl}${endpoint.sales_order.request_cancel}`, request).pipe(map(
            response =&gt; {
                return response.body.data;
            }));
    }
  </code></pre>
  <p>when i trying to console.log the response, it didn't appear. I think my function stop working in my post function at my global service class, what did i do wrong?</p>
  <p><strong>------------------ UPDATE OF MY CODE --------------------</strong></p>
  <p>i create HttpRequestInterceptor class to handle the error, here is my class :</p>
  <pre><code>@Injectable()
  export class HttpRequestInterceptor implements HttpInterceptor {
  
    user: UserModel;
    prevUrl: string = '';
    constructor(
      private loginSvc: LoginService, 
      private alertx: AlertService,
      private sharedService: SharedService) {
      this.sharedService.currentUserSubject.subscribe(user =&gt; this.user = user);
    }
  
    intercept(httpRequest: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
      this.sharedService.setLoading(true, httpRequest.url);
      return next.handle(httpRequest).pipe(catchError(err =&gt; {
        if ([401, 403].includes(err.status) /* &amp;&amp; this.user */) {
          // auto logout if 401 or 403 response returned from api
          this.sharedService.setLoading(false, httpRequest.url);
          this.loginSvc.removeLocal();
        }
        this.sharedService.setLoading(false, httpRequest.url);
        const error = err.statusText || err.statusText + ' ' + err.error?.message || err.statusText + ' ' + err.error?.error_description;
        this.alertx.error(error, {autoClose: true});
        return throwError(err.error?.message);
      }))
        .pipe(map&lt;HttpEvent&lt;any&gt;, any&gt;((evt: HttpEvent&lt;any&gt;) =&gt; {
          if (evt instanceof HttpResponse) {
            this.sharedService.setLoading(false, httpRequest.url);
          }
          return evt;
        }));
    }
  }
  </code></pre>
  <p>when i console.log my <code>err.error?.message</code> i can catch the error properly, then i the value passed to here :</p>
  <pre><code>    post&lt;T&gt;(url: string, body?: any, header?: HttpHeaders, param?: HttpParams): Observable&lt;HttpResponse&lt;T&gt;&gt;{
        return this.http.post&lt;T&gt;(url, body,
          {headers : header ? header : this.headers,
          observe: 'response',
          responseType: 'json',
          params: param})
          .pipe(catchError(err =&gt; {
            console.log(err);
            return throwError(err);
          }))
          .pipe(timeout(10000), catchError(err =&gt; {
            if (err instanceof TimeoutError) {
              this.alertx.error('Timeout Exception');
              return throwError('Timeout Exception');
            }
          }))
          .pipe(shareReplay());
    }
  </code></pre>
  <p>until there i still can catch the error properly when i <code>console.log(err)</code> but when i consume the <code>post</code> function, i can't catch the error, and i got error in my browser console. Here is my function :</p>
  <pre><code>  requestCancel(data: SelectItem, reasonCancel: string): Observable&lt;any&gt; {
        const request: RequestResponse&lt;SelectItem&gt; = new RequestResponse&lt;SelectItem&gt;(data);
        request.message = reasonCancel;
        return this.rest.post&lt;any&gt;(`${environment.apiUrl}${endpoint.sales_order.request_cancel}`, request).pipe(map(
            response =&gt; {
                return response.body.data;
            }))
            .pipe(catchError(err =&gt; {
                // i cannot get anything here
                console.log(err);
                return err;
        }));
    }
  </code></pre>
  <p>i can't log my error, it doesn't event print anything, i think my function crashed and throw this error instead :</p>
  <pre><code>TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
  </code></pre>
  <p>what did i still missed here?</p>