我有一个调用REST API的服务。 create
操作POST参数,然后使用HTTP标头中返回的id
获取创建的对象。返回对象时,Subject会传播该对象以通知其他组件。您可以注意到我没有调用catch
操作。我故意这样做,所以全局错误处理程序管理错误它第一次按预期工作,但第二次,不调用全局错误处理程序。
在Chrome控制台中,我在第一次通话后收到错误,但在rxjs/Subscriber.js
第二次通话后没有收到错误:
Subscriber.js:240 Uncaught
Response {_body: "{"message":"The query is not valid"}", status: 500, ok: false, statusText: "Internal Server Error", headers: Headers…}
SafeSubscriber.prototype.__tryOrUnsub = function (fn, value) {
try {
fn.call(this._context, value);
}
catch (err) {
this.unsubscribe();
throw err;
}
};
服务:
@Injectable()
export class SystemService {
private subject = new Subject<any>();
constructor(private http: Http) {
}
create(system: SdqlSystem) {
this.http.post(environment.apiEndpoint + 'systems', system)
.flatMap(res => {
const location = res.headers.get('Location');
return this.http.get(location);
})
.map(res => res.json())
.subscribe(data => this.subject.next(data));
}
get(id: string) {
this.http.get(environment.apiEndpoint + 'systems/' + id)
.map(res => res.json())
.subscribe(data => this.subject.next(data));
}
systems(): Observable<any> {
return this.subject.asObservable();
}
}
来自表格的电话:
onSubmit({value, valid}: { value: SdqlSystem, valid: boolean }) {
this.systemService.create(value);
}
全局错误处理程序:
@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
constructor(private logger: LoggingService, private notificationsService: NotificationsService) {
}
handleError(error: Response | any): void {
console.log('***** HANDLE ERROR *****');
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || body.message || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
this.logger.error(errMsg);
this.notificationsService.error('Error', errMsg);
throw error;
}
}
答案 0 :(得分:6)
重新考虑GlobalErrorHandler
中的错误会导致浏览器停止执行的未捕获异常。这就是它只运作一次的原因
解决方案只是不要重新抛出ErrorHandler。
更多细节:在这种情况下,onError
中没有提供subscribe()
- 函数。这就是rxjs/Subscriber.js
遇到catch
- __tryOrUnsub
部分的原因。
它尝试执行onError
- 函数但失败(因为没有),因此取消订阅Observable并抛出错误。
GlobalErrorHandler
选择它,进行记录和通知,然后重新抛出它
此时,错误成为Angular之外的未捕获异常。
(默认ErrorHandler不会重新抛出错误)
注意:此方法适用于标准的http调用,因为Response-Observable只发出一个值,然后仍然完成。 如果你有一个需要发出多个值的Observable,你将不得不以不同的方式处理错误,因为发出错误的Observable不会发出任何其他值,如Observable-Contract中所述:
<强>的OnError 强>
表示Observable已终止指定的错误条件,表示不会发出更多项目