Home > Net >  How to handle error while returning an observable in angular?
How to handle error while returning an observable in angular?

Time:11-21

I am creating an AuthGuard for my app..now when i try to load the component without getting logged in it should redirect me to the login page..But i am getting an error like following image error

and nothing happens.

I am throwing this error from my backend {"status":401,"message":"Auth Token Not found!"}} as there is no auth token

The following is the code of my AuthGuard

export class AuthGuardService implements CanActivate {

  constructor(private authService: AuthService, private router: Router) { }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> {

    return this.authService.checkLogin().pipe(
      map((data: HttpResponse) => {
        if (data.status == 200) {
          console.log("OUTPUT:", data)
          return true
        }
        else return false
      }),
    )

  }
}

The following is my function in AuthService:

 public checkLogin():Observable<HttpResponse> {

    return this.http.get<HttpResponse>('http://localhost:5000/auth/check-login', { withCredentials: true })

  }

Now how can i handle the errors like these and set a fallback value to false so if any error occurs then that route could not be accessed

CodePudding user response:

If I understood you correctly you want to achieve the following behavior:

  • If checkLogin() gets a response that indicates "success", the auth-guard shall return true
  • If checkLogin() gets an error-response, redirect the user to a fallback-page and return false

If you use the code below, please note that catchError() is only triggered if the backend responds with an exception, while map() is always triggered if a success-response comes in from the backend. Therefore, in the positive case, you can simply return true without checking the contents of the response. However, if you receive an exception from the backend, you can redirect the user to the fallback page using this.router.navigate() and then return of(false) to prevent the request from passing the auth guard.

export class AuthGuardService implements CanActivate {

  constructor(private authService: AuthService, private router: Router) { }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> {

    return this.authService.checkLogin().pipe(
      map(() => true),
      catchError(() => {
        this.router.navigate(['route-to-fallback-page']);
        return of(false);
      })
    );
  }
}

Alternative solution for Angular 7.1

Starting from Angular 7.1 you can just return a UrlTree-Object containing the fallback-route:

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> {

    return this.authService.checkLogin().pipe(
      map(() => true),
      catchError(() => this.router.parseUrl('/route-to-fallback-page'))
    );
  }

CodePudding user response:

use can use shared error response

this.http.get<HttpResponse>('http://localhost:5000/auth/check-login', { withCredentials: true }).pipe(
          catchError((error=>{
           
            this.getErrorMessage(error);
           return throwError(()=>error);
          }))
        )

The getErrorMessage Function will return the errors;

 private getErrorMessage(error:HttpErrorResponse){
   
      switch(error.status){
        
        case 400:{
          return this.toast.error(`Bad Request :${JSON.stringify(error.error?.Message)}`,error.status.toString())
        }
        case 401:{
          return this.toast.error(`Unauthorized :${JSON.stringify(error.error?.Message)}`,error.status.toString())
        }
        case 403:{
          return this.toast.error(`Access Denied :${JSON.stringify(error.error?.Message)}`,error.status.toString())
        }
        case 500:{
          return this.toast.error(`Internal Server Error :${JSON.stringify(error.error?.Message)}`,error.status.toString())
        }
        case 404:{
          return this.toast.error(`Page Not Found :${JSON.stringify(error.error?.Message)}`,error.status.toString())
        }
       default:{
        return this.toast.error('Check your internet connection!');
       }
      }
    }
  • Related