From 128fb9cc0718a07c08a2faf7e2c226539d2c8781 Mon Sep 17 00:00:00 2001 From: OJ Kwon Date: Tue, 29 Nov 2016 18:03:45 -0800 Subject: [PATCH] fix(AjaxObservable): catch XHR send failures to observer (#2159) --- spec/observables/dom/ajax-spec.ts | 55 ++++++++++++++++++++++++++++ src/observable/dom/AjaxObservable.ts | 8 ++-- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/spec/observables/dom/ajax-spec.ts b/spec/observables/dom/ajax-spec.ts index fd55f5e914..9914a43110 100644 --- a/spec/observables/dom/ajax-spec.ts +++ b/spec/observables/dom/ajax-spec.ts @@ -177,6 +177,33 @@ describe('Observable.ajax', () => { expect(error).to.be.an('error', 'wokka wokka'); }); + it('should error if send request throws', (done: MochaDone) => { + const expected = new Error('xhr send failure'); + + const obj = { + url: '/flibbertyJibbet', + responseType: 'text', + method: '', + createXHR: () => { + const ret = new MockXMLHttpRequest(); + ret.send = () => { + throw expected; + }; + return ret as any; + } + }; + + Rx.Observable.ajax(obj) + .subscribe(() => { + done(new Error('should not be called')); + }, (e: Error) => { + expect(e).to.be.equal(expected); + done(); + }, () => { + done(new Error('should not be called')); + }); + }); + it('should succeed on 200', () => { const expected = { foo: 'bar' }; let result; @@ -410,6 +437,34 @@ describe('Observable.ajax', () => { expect(MockXMLHttpRequest.mostRecent.url).to.equal('/flibbertyJibbet'); expect(MockXMLHttpRequest.mostRecent.data).to.equal('{"🌟":"🚀"}'); }); + + it('should error if send request throws', (done: MochaDone) => { + const expected = new Error('xhr send failure'); + + const obj = { + url: '/flibbertyJibbet', + responseType: 'text', + method: '', + body: 'foobar', + createXHR: () => { + const ret = new MockXMLHttpRequest(); + ret.send = () => { + throw expected; + }; + return ret as any; + } + }; + + Rx.Observable.ajax(obj) + .subscribe(() => { + done(new Error('should not be called')); + }, (e: Error) => { + expect(e).to.be.equal(expected); + done(); + }, () => { + done(new Error('should not be called')); + }); + }); }); describe('ajax.get', () => { diff --git a/src/observable/dom/AjaxObservable.ts b/src/observable/dom/AjaxObservable.ts index ecacddda03..4c558af454 100644 --- a/src/observable/dom/AjaxObservable.ts +++ b/src/observable/dom/AjaxObservable.ts @@ -248,10 +248,10 @@ export class AjaxSubscriber extends Subscriber { this.setupEvents(xhr, request); // finally send the request - if (body) { - xhr.send(body); - } else { - xhr.send(); + result = body ? tryCatch(xhr.send).call(xhr, body) : tryCatch(xhr.send).call(xhr); + if (result === errorObject) { + this.error(errorObject.e); + return null; } }