在 rxjs ajax.map 调用中处理异常
Handle exception in rxjs ajax.map call
我根据“fetch user demo" on the redux-observable website.
创作了一部史诗
我只是想知道如何向 ajax 请求添加错误处理。我的尝试:
const fetchCategoriesEpic = action$ =>
action$.ofType(FETCH_CATEGORIES)
.mergeMap(() =>
ajax.getJSON(`http://localhost:4000/categories`)
.map(
response => fetchCategoriesFulfilled(response),
error => console.log(error)
)
)
我正在测试,而我正在调用的 API 正在测试错误处理。仍然在控制台中得到这个并且应用程序崩溃:
ExceptionsManager.js:71 Unhandled JS Exception: ajax error 0
如果 this is the official docs 那么我是否应该摆脱地图并改用订阅?
我改成了这样:
import 'rxjs/add/operator/catch'
const fetchCategoriesEpic = action$ =>
action$.ofType(FETCH_CATEGORIES)
.mergeMap(() =>
ajax.getJSON(`http://localhost:4000/categories`)
.map(
response => fetchCategoriesFulfilled(response)
).catch( err => console.log(err))
)
但是得到了:
You provided undefined where a stream was expected. You can provide an
obserable, promise, array or iterable
更改为(根据 Jay Phelps 的回答 here):
const fetchCategoriesEpic = action$ =>
action$.ofType(FETCH_CATEGORIES)
.mergeMap(() =>
ajax.getJSON(`http://localhost:4000/categories`)
.map(response => fetchCategoriesFulfilled(response))
.catch( err => Observable.of(err.xhr.response))
)
得到:
Actions must be plain objects. Use custom middleware for async actions
我做错了什么?
https://github.com/Reactive-Extensions/RxJS-DOM is for RxJS v4, not v5. The docs for v5 are here: http://reactivex.io/rxjs/ and the source code here https://github.com/ReactiveX/rxjs.
这确实令人困惑,但由于复杂的原因,这是不幸的现实。
You provided undefined where a stream was expected. You can provide an obserable, promise, array or iterable
您收到此错误的原因确实是,您不是 return 需要的 catch
运算符使用流。
redux-observable 文档在此处提供了错误处理方法:https://redux-observable.js.org/docs/recipes/ErrorHandling.html
所以它看起来像这样:
const fetchCategoriesEpic = action$ =>
action$.ofType(FETCH_CATEGORIES)
.mergeMap(() =>
ajax.getJSON(`http://localhost:4000/categories`)
.map(
response => fetchCategoriesFulfilled(response)
)
.catch(error => Observable.of({
type: FETCH_CATEGORIES_REJECTED,
error
}))
)
如果你真的不想捕获错误和return另一个Observable(比如单个错误操作的Observable)那么你可以使用.do()
只记录错误:
const fetchCategoriesEpic = action$ =>
action$.ofType(FETCH_CATEGORIES)
.mergeMap(() =>
ajax.getJSON(`http://localhost:4000/categories`)
.map(
response => fetchCategoriesFulfilled(response)
)
.do({
error: err => console.log(err)
})
)
但是,如果您没有发现错误,它将向上传播到源链,终止此 Epic,然后继续传播终止您的根 Epic,从而使您的应用可能无法使用。
虽然我不推荐这样做,但如果你真的想捕获错误但只是吞下它而不进行分派和错误操作,你可以这样做:
const fetchCategoriesEpic = action$ =>
action$.ofType(FETCH_CATEGORIES)
.mergeMap(() =>
ajax.getJSON(`http://localhost:4000/categories`)
.map(
response => fetchCategoriesFulfilled(response)
)
.catch(error => {
console.error(error);
return Observable.empty();
})
)
再次强调,我强烈建议不要这样做——如果有一个错误你足够关心来捕捉它,你可能应该以某种方式处理它,例如通过分派错误操作和处理来向用户显示错误那。
编辑:根据您的新增内容
.catch( err => Observable.of(err.xhr.response))
Actions must be plain objects. Use custom middleware for async actions
确实,您的史诗现在发出错误的 XHR 响应,而不是 redux 操作。您的史诗只能发出动作。
我根据“fetch user demo" on the redux-observable website.
创作了一部史诗我只是想知道如何向 ajax 请求添加错误处理。我的尝试:
const fetchCategoriesEpic = action$ =>
action$.ofType(FETCH_CATEGORIES)
.mergeMap(() =>
ajax.getJSON(`http://localhost:4000/categories`)
.map(
response => fetchCategoriesFulfilled(response),
error => console.log(error)
)
)
我正在测试,而我正在调用的 API 正在测试错误处理。仍然在控制台中得到这个并且应用程序崩溃:
ExceptionsManager.js:71 Unhandled JS Exception: ajax error 0
如果 this is the official docs 那么我是否应该摆脱地图并改用订阅?
我改成了这样:
import 'rxjs/add/operator/catch'
const fetchCategoriesEpic = action$ =>
action$.ofType(FETCH_CATEGORIES)
.mergeMap(() =>
ajax.getJSON(`http://localhost:4000/categories`)
.map(
response => fetchCategoriesFulfilled(response)
).catch( err => console.log(err))
)
但是得到了:
You provided undefined where a stream was expected. You can provide an obserable, promise, array or iterable
更改为(根据 Jay Phelps 的回答 here):
const fetchCategoriesEpic = action$ =>
action$.ofType(FETCH_CATEGORIES)
.mergeMap(() =>
ajax.getJSON(`http://localhost:4000/categories`)
.map(response => fetchCategoriesFulfilled(response))
.catch( err => Observable.of(err.xhr.response))
)
得到:
Actions must be plain objects. Use custom middleware for async actions
我做错了什么?
https://github.com/Reactive-Extensions/RxJS-DOM is for RxJS v4, not v5. The docs for v5 are here: http://reactivex.io/rxjs/ and the source code here https://github.com/ReactiveX/rxjs.
这确实令人困惑,但由于复杂的原因,这是不幸的现实。
You provided undefined where a stream was expected. You can provide an obserable, promise, array or iterable
您收到此错误的原因确实是,您不是 return 需要的 catch
运算符使用流。
redux-observable 文档在此处提供了错误处理方法:https://redux-observable.js.org/docs/recipes/ErrorHandling.html
所以它看起来像这样:
const fetchCategoriesEpic = action$ =>
action$.ofType(FETCH_CATEGORIES)
.mergeMap(() =>
ajax.getJSON(`http://localhost:4000/categories`)
.map(
response => fetchCategoriesFulfilled(response)
)
.catch(error => Observable.of({
type: FETCH_CATEGORIES_REJECTED,
error
}))
)
如果你真的不想捕获错误和return另一个Observable(比如单个错误操作的Observable)那么你可以使用.do()
只记录错误:
const fetchCategoriesEpic = action$ =>
action$.ofType(FETCH_CATEGORIES)
.mergeMap(() =>
ajax.getJSON(`http://localhost:4000/categories`)
.map(
response => fetchCategoriesFulfilled(response)
)
.do({
error: err => console.log(err)
})
)
但是,如果您没有发现错误,它将向上传播到源链,终止此 Epic,然后继续传播终止您的根 Epic,从而使您的应用可能无法使用。
虽然我不推荐这样做,但如果你真的想捕获错误但只是吞下它而不进行分派和错误操作,你可以这样做:
const fetchCategoriesEpic = action$ =>
action$.ofType(FETCH_CATEGORIES)
.mergeMap(() =>
ajax.getJSON(`http://localhost:4000/categories`)
.map(
response => fetchCategoriesFulfilled(response)
)
.catch(error => {
console.error(error);
return Observable.empty();
})
)
再次强调,我强烈建议不要这样做——如果有一个错误你足够关心来捕捉它,你可能应该以某种方式处理它,例如通过分派错误操作和处理来向用户显示错误那。
编辑:根据您的新增内容
.catch( err => Observable.of(err.xhr.response))
Actions must be plain objects. Use custom middleware for async actions
确实,您的史诗现在发出错误的 XHR 响应,而不是 redux 操作。您的史诗只能发出动作。