Redux-observable: RFC: onErrorReturn() operator

Created on 6 Sep 2016  路  4Comments  路  Source: redux-observable/redux-observable

Some Rx implementations contain an onErrorReturn operator. http://reactivex.io/documentation/operators/catch.html (scroll down and select it from RxJava list)

instructs an Observable to emit a particular item when it encounters an error, and then terminate normally

image

The onErrorReturn method returns an Observable that mirrors the behavior of the source Observable, unless that Observable invokes onError in which case, rather than propagating that error to the observer, onErrorReturn will instead emit a specified item and invoke the observer鈥檚 onCompleted method. javadoc

This operator is usually similar to .catch() but that it expects your provided selector to return a single _value_ instead of an Observable.

In practice this is exactly what people do 99% of the time in redux-observable.

Using .catch()

// return an Observable
.catch(error => Observable.of({
  type: FETCH_USER_REJECTED,
  payload: error.xhr.response,
  error: true
}))
const fetchUserEpic = action$ =>
  action$.ofType(FETCH_USER)
    .mergeMap(action =>
      ajax.getJSON(`/api/users/${action.payload}`)
        .map(fetchUserFulfilled)
        .catch(error => Observable.of({
            type: FETCH_USER_REJECTED,
            payload: error.xhr.response,
            error: true
        }))
    );

Using .onErrorReturn()

// Return a value
.onErrorReturn(error => ({
  type: FETCH_USER_REJECTED,
  payload: error.xhr.response,
  error: true
})
const fetchUserEpic = action$ =>
  action$.ofType(FETCH_USER)
    .mergeMap(action =>
      ajax.getJSON(`/api/users/${action.payload}`)
        .map(fetchUserFulfilled)
        .onErrorReturn(error => ({
            type: FETCH_USER_REJECTED,
            payload: error.xhr.response,
            error: true
        })
    );

Or more likely with action creators:

.onErrorReturn(error => fetchUserRejected(error.xhr.response))

I've noticed most people don't fully understand what .catch() is doing--that you're returning an observable that should be switched to, on error, which itself may or may not terminate. While .catch() is certainly handy, onErrorReturn on the other hand has more obvious semantics for redux-observable use cases.

This probably belongs in RxJS v5 core, but before I pitch it there I wanted to confirm the community agrees this would be super helpful. Worst case, we can add onErrorReturn to the ActionsObservable prototype, but I'm confident core will want it too.

Cc/ @blesh

RFC feature request

Most helpful comment

@BerkeleyTrue there's some internal discussion around this right now. There is a high probability RxJS will start adding more operators (like this one), even though the last public discussion in that thread ReactiveX/rxjs#1928 (and others) was that we didn't want to add more.

The big kicker is file size bloat for UMD and import Rx from 'rxjs' usage. To still keep that lean, we're considering shifting a number of existing operators (and any new ones) to separate builds for UMD and namespaced for CJS/ES.

e.g.

import Rx from 'rxjs';
import 'rxjs/kitchen-sink';
// or
// import 'rxjs/kitch-sink/add/operator/onErrorReturn';

This would be an easier decision if RxJS had a true monorepo, but several of us have tried and all gave up (for now) frustrated with our super super complicated build requirements. It sounds silly, but we all thought "it can't be _that_ hard" and ultimately came out saying "mother of gawd..."

No promises, either way. But for now I'm waiting until a more formal decision is made around this for RxJS.

Others are (of course) certainly welcome to take my code from ReactiveX/rxjs#1928 and either keep a local copy in their app or publish their own library.

As an aside, we're going to start being a little more formal with RxJS meetings--now being held every 2 weeks--I'm proposing to the group next meeting that we release meeting agenda and notes similar to reactjs/core-notes and emberjs/core-notes.

All 4 comments

This is 99.99% of my use of the catch operator.

After discussing with numerous people, I think this is a great addition to core so I've made a PR for this. We'll bikeshed there. https://github.com/ReactiveX/rxjs/pull/1928

Since this will not be added to core, are we adding an operator to this library?

@BerkeleyTrue there's some internal discussion around this right now. There is a high probability RxJS will start adding more operators (like this one), even though the last public discussion in that thread ReactiveX/rxjs#1928 (and others) was that we didn't want to add more.

The big kicker is file size bloat for UMD and import Rx from 'rxjs' usage. To still keep that lean, we're considering shifting a number of existing operators (and any new ones) to separate builds for UMD and namespaced for CJS/ES.

e.g.

import Rx from 'rxjs';
import 'rxjs/kitchen-sink';
// or
// import 'rxjs/kitch-sink/add/operator/onErrorReturn';

This would be an easier decision if RxJS had a true monorepo, but several of us have tried and all gave up (for now) frustrated with our super super complicated build requirements. It sounds silly, but we all thought "it can't be _that_ hard" and ultimately came out saying "mother of gawd..."

No promises, either way. But for now I'm waiting until a more formal decision is made around this for RxJS.

Others are (of course) certainly welcome to take my code from ReactiveX/rxjs#1928 and either keep a local copy in their app or publish their own library.

As an aside, we're going to start being a little more formal with RxJS meetings--now being held every 2 weeks--I'm proposing to the group next meeting that we release meeting agenda and notes similar to reactjs/core-notes and emberjs/core-notes.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

connected-mgosbee picture connected-mgosbee  路  5Comments

ksaldana1 picture ksaldana1  路  4Comments

ericis picture ericis  路  3Comments

MikeRyanDev picture MikeRyanDev  路  3Comments

selfrefactor picture selfrefactor  路  7Comments