如何为所有 redux-observable epics 添加全局错误处理程序?

How to add a global error handler for all redux-observable epics?

我使用 redux-observable 开发 React Native 应用程序。我有 10+ epics,全部以 .catch(err => console.error(err)) 结尾,以便在史诗中出现错误时显示 React Native "Red box"(参见 https://facebook.github.io/react-native/docs/debugging.html#errors)。

我如何定义一个全局错误处理程序,供所有 epics 使用(它们稍后由 combineEpics 函数组合)?

redux-observable 几乎所有你会做的事情都依赖于 RxJS 的惯用范式。当您将 Epics 组合在一起时,您正在创建一个具有正常 function (action$, store) 签名的新史诗。所以这个新的 Epic 代表了那些个体 Epics 的所有输出,包括错误。

您可以通过定义自己的 rootEpic 并编写 combineEpics() 调用的结果来利用这一事实。由于 Epics 是工厂,您需要记得传递 (action$, store)!

这是一种方法:

export const rootEpic = (action$, store) =>
  combineEpics(epic1, epic2, epic3)(action$, store) // <-- call epic w/ args
    .do({ error: err => console.error(err) });

你可能不应该为此使用 .catch() 运算符,因为 .catch() 用于 返回 一些其他 Observable 来代替,当有一个错误。如果您只想记录错误(而不是尝试恢复),.do() 是理想的运算符——它的目的是允许您执行对流没有影响的外部副作用(如日志记录)本身。

作曲 Epics 非常强大,不仅在这种情况下,而且我们计划很快描述的许多其他情况。

.catch()运算符相关,您可能还对the RFC for better default error handling感兴趣。

2020 年更新

import { concat, of } from 'rxjs';
import { combineEpics } from 'redux-observable';
import { catchError } from 'rxjs/operators';

export const rootEpic = (action$, store) =>
  combineEpics(epic1, epic2, epic3)(action$, store)
    .pipe((error, caught) => concat(caught));
import { createEpicMiddleware } from 'redux-observable';
const epicMiddleware = createEpicMiddleware();
epicMiddleware.run((action$, store) => rootEpics(action$, store));

您还可以像这样传递 redux 错误操作:

concat(of(reduxActionForError), caught));