我有一个http全球服务,它被称为所有服务;所以我可以通过例子来管理;错误,警报,变量等。
customers.service.ts
export class CustomersService {
childUrl = environment.apiUrl + 'customers';
constructor(
private http: HttpClient,
private globalService: GlobalService
) {
}
public get(childUrl) {
return this.globalService.get(this.childUrl)
.catch((res: Response) => this.handleError(res));
}
...
private handleError(err) {
return Observable.throw(err);
}
}
global.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import { environment } from '../../environments/environment';
@Injectable()
export class GlobalService {
url: string,
constructor(private http: HttpClient) {
this.headers = new HttpHeaders()
.set('Content-Type', 'application/json; charset=utf-8')
.set('Accept', 'application/json');
}
public prepare ( vars ) {
this.url = environment.apiUrl + vars.childUrl;
}
public get( childUrl) {
this.prepare ({childUrl} );
return this.http.get(this.url, { headers: this.headers, observe: 'response'})
.catch((res: Response) => this.handleError(res);
}
private handleError(err) {
return Observable.throw(err);
}
}
客户-list.component
export class CustomersListComponent implements OnInit {
public customers: Array <any>;
constructor (private customersService: CustomersService ) { }
ngOnInit() {
this.get();
}
private get(): void {
this.customerService
.get()
.subscribe((data) => {this.customers = data.data; console.log(data) },
error => console.log(error),
() => console.log('Get all Items complete'));
}
}
在角度4.3之前我有可观察量,我可以捕获错误,并在组件中的子服务中抛出一个可观察的全局服务。现在它不起作用,我不知道如何管理catch,并用observables处理错误
在新的角度指南中: https://angular.io/guide/http#error-handling
只是以简单的方式管理错误,
http
.get<ItemsResponse>('/api/items')
.subscribe(
data => {...},
(err: HttpErrorResponse) => {
if (err.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly.
console.log('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,
console.log(`Backend returned code ${err.status}, body was: ${err.error}`);
}
}
});
现在管理这个的正确方法是什么?
答案 0 :(得分:6)
您做仍然有可观察对象,您基本上可以保留现有的组件代码。您需要更改的是使用新HttpClient
的服务代码。
这是我的新服务:
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/map';
import { IProduct } from './product';
@Injectable()
export class ProductService {
private _productUrl = './api/products/products.json';
constructor(private _http: HttpClient) { }
getProducts(): Observable<IProduct[]> {
return this._http.get<IProduct[]>(this._productUrl)
.do(data => console.log('All: ' + JSON.stringify(data)))
.catch(this.handleError);
}
private handleError(err: HttpErrorResponse) {
// 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 Error) {
// 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 Observable.throw(errorMessage);
}
}
这是我的组件中的方法,它基本上没有变化:
ngOnInit(): void {
this._productService.getProducts()
.subscribe(products => this.products = products,
error => this.errorMessage = <any>error);
}
答案 1 :(得分:2)
我终于找到了一个解决方案,错误是对象,所以在angular 4.3之前,错误对象是一个Response,现在它的HttpErrorResponse,无论如何我们得到了对象,所以我们可以要求属性。大多数函数不考虑错误状态0,o当服务器不工作时没有任何东西,或者角度4.3中的拦截器或你在错误管理中做的任何事情都没有产生正确的状态。
我发现的最终解决方案只是简单地从错误对象中询问对象属性,并且在我不希望显示已知错误的后端错误的情况下,我可以定义消息错误。
查找environment.ts文件(angular-cli创建此文件):
export const environment = {
production: false,
apiUrl: 'http://localhost:3000/',
httpErrors: {
0: { 'msg': 'Server is not available'},
404: { 'msg': 'Page not Found'},
401: { 'msg': 'Not Authorized'}
}
};
然后处理全局服务的错误可以是:
private handleError(err: any) {
console.log( 'Error global service');
console.log(err);
let errorMessage = '';
if (err.hasOwnProperty('status') ) { // if error has status
if (environment.httpErrors.hasOwnProperty(err.status)) {
errorMessage = environment.httpErrors[err.status].msg; // predefined errors
} else {
errorMessage = `Error status: ${err.status}`;
if (err.hasOwnProperty('message')) {
errorMessage += err.message;
}
}
}
if (errorMessage === '') {
if (err.hasOwnProperty('error') && err.error.hasOwnProperty('message') ) { // if error has status
errorMessage = `Error: ${err.error.message}`;
}
}
if (errorMessage === '') errorMessage = environment.httpErrors[0].msg; +// no errors, then is connection error
this.snackBar.open(errorMessage, 'Close', {
duration: 5000
});
console.error(errorMessage);
return Observable.throw(errorMessage);
}
你的拦截器中的
import {HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
@Injectable()
export class InterceptorService implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (localStorage.getItem('SignIn-Token')) {
req = req.clone({
setHeaders: {
authorization: localStorage.getItem('SignIn-Token')
}
});
}
return next.handle(req).catch(err => {
if (err instanceof HttpErrorResponse) {
console.log('interceptor error');
console.log(err);
if (err.status === 401) {
// JWT expired, can be setted to go to login
return Observable.throw(err);
} else {
return Observable.throw(err);
}
}
});
}
}
如果您通过示例使用下面的代码在拦截器中出错,那么handleError仍将起作用:
return next.handle(req).catch(err => {
if (err instanceof HttpErrorResponse) {
console.log('interceptor error');
console.log(err);
if (err.status === 401) {
// JWT expired, can be setted to go to login
return Observable.throw(err);
}
// here you are not return observable so, your global service get nothing of status ....
}
});
答案 2 :(得分:1)
为错误场景定义严格类型,如下所示
export interface Error{
code:number;
error:string[];
errorType:ErrorType;
}
export enum ErrorType{
FATAL_ERROR,
SYSTEM_ERROR
}
使用handleError
常用方法进行处理,方法如下修改
private handleError(error) {
if(typeof error === Response){
return Observable.throw(err);
} else if(typeof error === Error){
if(error && error.errorMessages && errorMessages.length){
error.errorMessages.forEach(msg=> console.log(error.error));
}
}
}