如何在Angular组件中借助RxJS捕获API请求错误
问题解决:在Component中捕获NgRx流程中的API错误
问题根源
你当前的Component订阅的是combineLatest生成的流,这个流在dispatch完ADD_TO_CART action后就返回了of(null)并正常完成,完全独立于后续Effects调用API的流。因此不管API请求成功或失败,Component的订阅都会进入成功回调,根本捕获不到API错误。
解决方案
要在Component中捕获错误,需要通过NgRx的Action机制传递错误状态:先在Effects中捕获API错误并分发失败Action,再让Component监听成功/失败Action的状态变化。
步骤1:添加失败Action
修改action.ts,新增处理添加购物车失败的Action:
// action.ts addToCartFailure(error: any): any { return { type: CheckoutActions.ADD_TO_CART_FAILURE, payload: { error } }; }
步骤2:在Effects中捕获并传递错误
修改effect.ts,为API调用添加错误捕获逻辑,出错时分发失败Action:
// effect.ts @Effect() addToCart$ = this.actions$.pipe( ofType(CheckoutActions.ADD_TO_CART), flatMap((action: any) => { return this.checkoutService.createNewLineItem(action.payload).pipe( map((result) => this.actions.addToCartSuccess()), // 捕获API错误,分发失败Action catchError((error) => of(this.actions.addToCartFailure(error))) ); }) );
步骤3:在Component中监听Action结果
修改component.ts,让流在dispatch Action后,继续监听成功/失败Action的状态,从而在Component中处理结果:
// component.ts addToCart() { combineLatest( this.product$, this.variantId$, this.specTemplateStatusAndValue$.pipe( map((statusAndValue) => statusAndValue.value) ) ) .pipe( takeUntil(this.unsubscribe$), first(), flatMap(([product, variantId, specTemplateValue]) => { // 分发添加购物车Action this.store.dispatch( this.checkoutActions.addToCart( variantId, product.normal_product ? 1 : 1, specTemplateValue, [] ) ); // 监听后续的成功/失败Action return this.actions$.pipe( ofType( CheckoutActions.ADD_TO_CART_SUCCESS, CheckoutActions.ADD_TO_CART_FAILURE ), first(), map(action => ({ type: action.type, payload: action.payload })) ); }) ) .subscribe( (result) => { if (result.type === CheckoutActions.ADD_TO_CART_SUCCESS) { this.router.navigate(['/checkout', 'cart']); } else if (result.type === CheckoutActions.ADD_TO_CART_FAILURE) { console.error(':::::ERROR', result.payload.error); // 这里添加你的错误处理逻辑(比如提示用户) } }, // 捕获combineLatest流本身的错误(如product$等数据源出错) (err) => console.error('数据源流错误', err) ); }
额外说明
- Service中的
http.post请求出错时,错误会传递到Effects中被catchError捕获,不会被吞掉。 - 如果需要将错误状态持久化到Store中,可以在Reducer中处理
ADD_TO_CART_FAILUREAction,将错误信息存入State,再通过@Select装饰器在Component中订阅错误状态。
内容的提问来源于stack exchange,提问作者aRtoo
相关产品推荐
相关产品推荐

