user3284063
user3284063

Reputation: 685

How to redirect to to another page on http error?

I have the following code inside a class that derives from Angular HttpInterceptor:

handleError(error: unknown): Promise<boolean> {
        if (error instanceof HttpErrorResponse) {
            return this.router.navigate([NOT_FOUND_URL, this.errorDescriptionProvider.getHttpErrorDescription(error)]);           
        }
        else
            return this.router.navigate([NOT_FOUND_URL, this.errorDescriptionProvider.getUnspecifiedNetworkErrorDescription()])
    }

and the

intercept(req: HttpRequest<T>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    const stream =  next
        .handle(req)
        .pipe
        (
           catchError(x => from(this.handleError(x)))              
        );

        //Error that boils down to: is not assignable to Observable<HttpEvent<unknow>> since its type is Observable<boolean |....>
        return  stream;
}

How to achieve the redirecting on http error?

Upvotes: 0

Views: 2290

Answers (3)

dasunse
dasunse

Reputation: 3089

Here is an example of every unorthorized requests will redirect to Login page

import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs/Rx";
import { Router } from "@angular/router";
import { tap } from "rxjs/internal/operators";


@Injectable()
export class UnAuthorizedInterceptor implements HttpInterceptor {
  constructor(private router: Router) { }
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(tap(() => { },
      (err: any) => {
        if (err instanceof HttpErrorResponse) {
          if ((err.status === 401) || (err.status === 403)) {
            this.router.navigate(['/login']);
          } else {
            return;
          }
        }
      }));
  }
}

And add { provide: HTTP_INTERCEPTORS, useClass: UnAuthorizedInterceptor, multi: true } as a provider in app.module.ts file

Upvotes: 1

Eliseo
Eliseo

Reputation: 57939

If you want to send to a errorPage of your angular just inject the Router in your service and navigate sending the data in navigate.extra

A fool service

  getData()
  {
    return throwError({error:"NotExist"}).pipe(catchError(x=>{
      return this.error(x)
    }))

  }
  error(x):Observable<any>
  {
    console.log(x)
    this.router.navigate(['/error'],{ state: { error: x } })
    return of(null);
  }

Your error.component

@Component({
  selector: 'error',
  template: `<h1>ERROR</h1>
  <pre>{{ state$ | async | json }}</pre>
  `,
  styles: [`h1 { font-family: Lato; }`]
})
export class ErrorComponent implements OnInit  {
private state$: Observable<object>;

  constructor(public activatedRoute: ActivatedRoute) { }
    ngOnInit() {
      this.state$ = this.activatedRoute.paramMap
      .pipe(map(() => window.history.state))
  }

}

see the stackblitz

Upvotes: 1

Huantao
Huantao

Reputation: 935

you can make your handleError function return type void (its goal is to navigate).

and in catchError

  catchError(err => {
    if (err instanceof HttpErrorResponse) {
      //call your handle error function
       handleError(err);
    }
    return throwError(err);
  }),

Upvotes: 0

Related Questions