Skip to content

Commit c5ead88

Browse files
committed
fix(Observable.forEach): errors thrown in nextHandler reject returned promise
This is done to match the es-observable spec. fixes #1184
1 parent 22fcbcf commit c5ead88

File tree

2 files changed

+26
-20
lines changed

2 files changed

+26
-20
lines changed

spec/Observable-spec.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,21 @@ describe('Observable', function () {
7272

7373
expect(typeof result.then).toBe('function');
7474
});
75+
76+
it('should reject promise if nextHandler throws', function (done) {
77+
var results = [];
78+
Observable.of(1,2,3).forEach(function (x) {
79+
if (x === 3) {
80+
throw new Error('NO THREES!');
81+
};
82+
results.push(x);
83+
})
84+
.then(done.fail, function (err) {
85+
expect(err).toEqual(new Error('NO THREES!'));
86+
expect(results).toEqual([1,2]);
87+
})
88+
.then(done);
89+
});
7590
});
7691

7792
describe('subscribe', function () {

src/Observable.ts

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {ConnectableObservable} from './observable/ConnectableObservable';
1111
import {Subject} from './Subject';
1212
import {Notification} from './Notification';
1313
import {toSubscriber} from './util/toSubscriber';
14+
import {tryCatch} from './util/tryCatch';
15+
import {errorObject} from './util/errorObject';
1416

1517
import {combineLatest as combineLatestStatic} from './operator/combineLatest-static';
1618
import {concat as concatStatic} from './operator/concat-static';
@@ -136,27 +138,16 @@ export class Observable<T> implements CoreOperators<T> {
136138
throw new Error('no Promise impl found');
137139
}
138140

139-
let nextHandler: any;
141+
const source = this;
140142

141-
if (thisArg) {
142-
nextHandler = function nextHandlerFn(value: any): void {
143-
const { thisArg, next } = <any>nextHandlerFn;
144-
return next.call(thisArg, value);
145-
};
146-
nextHandler.thisArg = thisArg;
147-
nextHandler.next = next;
148-
} else {
149-
nextHandler = next;
150-
}
151-
152-
const promiseCallback = function promiseCallbackFn(resolve: Function, reject: Function) {
153-
const { source, nextHandler } = <any>promiseCallbackFn;
154-
source.subscribe(nextHandler, reject, resolve);
155-
};
156-
(<any>promiseCallback).source = this;
157-
(<any>promiseCallback).nextHandler = nextHandler;
158-
159-
return new PromiseCtor<void>(promiseCallback);
143+
return new PromiseCtor<void>((resolve, reject) => {
144+
source.subscribe((value: T) => {
145+
const result: any = tryCatch(next).call(thisArg, value);
146+
if (result === errorObject) {
147+
reject(errorObject.e);
148+
}
149+
}, reject, resolve);
150+
});
160151
}
161152

162153
_subscribe(subscriber: Subscriber<any>): Subscription | Function | void {

0 commit comments

Comments
 (0)