我在这里使用redux-observable
并在测试错误处理方面遇到了一些问题。
请参阅以下注销用户史诗:
const logoutUserEpic = (action$) => action$
.ofType(LOGOUT_USER)
.mergeMap(() =>
Observable.from(
graphQl(AuthLogout)
.catch((error) => failure(error))
)
.mergeMap(() => Observable.of(
receive(),
push('/login')
)
)
)
这是一项测试,可以模拟graphQl
服务,以确保在承诺拒绝时触发失败操作:
it('should return the error action', () => {
const error = Error('fail')
request.graphQl = () => Promise.reject(error)
const action$ = ActionsObservable.of((logoutUser()))
return logoutUserEpic(action$)
.toArray()
.forEach((actions) => {
expect(actions).toEqual([{
meta: { isFetching: false },
payload: error,
type: FAILURE
}])
})
})
在测试中,它调度在mergeMap中展平的动作,而不是catch中预期的失败动作。
将错误处理设置为这样是有效还是我用RxJ显示我的无效?
答案 0 :(得分:2)
问题是你正在捕获Promise本身的错误,然后你的mergeMap
忽略了Promise的结果,所以你丢掉了failure(error)
(可能是一个错误动作)< / p>
const logoutUserEpic = (action$) => action$
.ofType(LOGOUT_USER)
.mergeMap(() =>
Observable.from(
graphQl(AuthLogout)
.catch((error) => failure(error))
// If there is an error, you caught it and transformed it
// instead into a failure(error) down the success path
)
// If there was an error, it is now no longer an error and this
// mergeMap will just throw that failure(error) away
.mergeMap(() => Observable.of(
receive(),
push('/login')
)
)
)
相反,您应该使用RxJS捕获错误,在这种情况下将其放在mergeMap
之后 - 请注意RxJS的catch
和Promise catch
是相似但不一样的!
const logoutUserEpic = (action$) => action$
.ofType(LOGOUT_USER)
.mergeMap(() =>
Observable.from(graphQl(AuthLogout))
.mergeMap(() => Observable.of(
receive(),
push('/login')
))
.catch((error) => Observable.of(failure(error)))
)