I've migrate our application from angular 2 to angular 5 and also migrrate from the deprecated Http to the new HttpClient.
In the old application i had the following Http-Client to redirect from error to a specific page.
import {Router} from "@angular/router"; import {Injectable} from "@angular/core"; import {ConnectionBackend, Http, Request, RequestOptions, RequestOptionsArgs, Response} from "@angular/http"; import {Observable} from "rxjs/Observable"; import "rxjs/add/operator/catch"; @Injectable() export class HttpService extends Http { constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private router: Router) { super(backend, defaultOptions); } request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> { return super.request(url, options) .catch(this.catchErrors()); } private catchErrors() { return (res: Response) => { if (this.isError(res)) { console.log(`Internal server error occured (${res.status} - ${res.statusText})`); this.router.navigateByUrl('/error'); } else if (this.isUnauthorized(res)) { console.log(`User is not authenticated - not logged in or the session expired? (${res.status} - ${res.statusText})`); this.router.navigateByUrl('/logout'); } else if (this.isForbidden(res)) { console.log(`User does not have necessary permissions for the resource (${res.status} - ${res.statusText}): ${res.url}`); this.router.navigateByUrl('/forbidden'); } return Observable.throw(res); }; } private isError(res: Response): boolean { return res && res.status === 500; } private isUnauthorized(res: Response): boolean { return res && res.status === 401; } private isForbidden(res: Response): boolean { return res && res.status === 403; } }
And now I have refactored this one to a HttpInterceptor
import {Router} from "@angular/router"; import {Injectable} from "@angular/core"; import {Observable} from "rxjs/Observable"; import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from "@angular/common/http"; @Injectable() export class HttpService implements HttpInterceptor { constructor(private router: Router) { } private catchErrors() { return (res: HttpResponse<any>) => { if (this.isError(res)) { console.log(`Internal server error occured (${res.status} - ${res.statusText})`); this.router.navigateByUrl('/error'); } else if (this.isUnauthorized(res)) { console.log(`User is not authenticated - not logged in or the session expired? (${res.status} - ${res.statusText})`); this.router.navigateByUrl('/logout'); } else if (this.isForbidden(res)) { console.log(`User does not have necessary permissions for the resource (${res.status} - ${res.statusText}): ${res.url}`); this.router.navigateByUrl('/forbidden'); } return Observable.throw(res); }; } private isError(res: HttpResponse<any>): boolean { return res && res.status === 500; } private isUnauthorized(res: HttpResponse<any>): boolean { return res && res.status === 401; } private isForbidden(res: HttpResponse<any>): boolean { return res && res.status === 403; } intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(req).catch(this.catchErrors()); } }
But now the navigateByUrl has no effect and the site is even accessible.
Has someone any idea how to fix this?
you can try with this solution
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const started = Date.now();
/**
* Handle newly created request with updated header (if given)
*/
return next.handle(req).do((event: HttpEvent<any>) => {
/**
* Sucessfull Http Response Time.
*/
if (event instanceof HttpResponse) {
const elapsed = Date.now() - started;
}
}, (err: any) => {
/**
* redirect to the error_handler route according to error status or error_code
*/
if (err instanceof HttpErrorResponse) {
switch (err.status) {
case 500:
console.log(`Internal server error occured (${err.status} - ${err.statusText})`);
this.router.navigateByUrl('/error');
break;
case 400:
console.log(`User is not authenticated - not logged in or the session expired? (${err.status} - ${err.statusText})`);
this.router.navigateByUrl('/logout');
break;
case 403:
console.log(`User does not have necessary permissions for the resource (${err.status} - ${err.statusText}): ${err.url}`);
this.router.navigateByUrl('/forbidden');
break;
}
}
});
}
You didn't get any console error message?
I would try the following code:
import {Router} from "@angular/router";
import {Injectable} from "@angular/core";
import {Observable} from "rxjs/Observable";
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from "@angular/common/http";
@Injectable()
export class HttpService implements HttpInterceptor {
constructor(private router: Router) {
}
private catchErrors(httpError) {
if (this.isError(res)) {
console.log(`Internal server error occured (${res.status} - ${res.statusText})`);
this.router.navigateByUrl('/error');
} else if (this.isUnauthorized(res)) {
console.log(`User is not authenticated - not logged in or the session expired? (${res.status} - ${res.statusText})`);
this.router.navigateByUrl('/logout');
} else if (this.isForbidden(res)) {
console.log(`User does not have necessary permissions for the resource (${res.status} - ${res.statusText}): ${res.url}`);
this.router.navigateByUrl('/forbidden');
}
return Observable.throw(res);
}
private isError(res: HttpResponse<any>): boolean {
return res && res.status === 500;
}
private isUnauthorized(res: HttpResponse<any>): boolean {
return res && res.status === 401;
}
private isForbidden(res: HttpResponse<any>): boolean {
return res && res.status === 403;
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).catch(httpError => this.catchErrors(httpError));
}
}
You need to make sure that your catchErrors
function is binded to your HttpService
class and do a Observable.throw
to return a failed Observable
.
Also check the type of httpError
, in Angular 6+ I'm using HttpErrorResponse
but I'm not sure what type is on older versions.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.