Skip to content

Commit

Permalink
fix(ajax): Handle timeouts as errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Bryan Bonnet committed May 6, 2018
1 parent 7e4cef4 commit 8bab826
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 31 deletions.
72 changes: 46 additions & 26 deletions spec/observables/dom/ajax-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,38 @@ describe('Observable.ajax', () => {
});
});

it('should error on timeout of asynchronous request', (done) => {
const obj: Rx.AjaxRequest = {
url: '/flibbertyJibbet',
responseType: 'text',
timeout: 10
};

Rx.Observable.ajax(obj)
.subscribe((x: any) => {
throw 'should not have been called';
}, (e) => {
expect(e.status).to.equal(0);
expect(e.xhr.method).to.equal('GET');
expect(e.xhr.async).to.equal(true);
expect(e.xhr.timeout).to.equal(10);
expect(e.xhr.responseType).to.equal('text');
});

const request = MockXMLHttpRequest.mostRecent;

expect(request.url).to.equal('/flibbertyJibbet');

setTimeout(() => {
request.respondWith({
'status': 200,
'contentType': 'text/plain',
'responseText': 'Wee! I am text!'
});
done();
}, 1000);
});

it('should create a synchronous request', () => {
const obj: Rx.AjaxRequest = {
url: '/flibbertyJibbet',
Expand Down Expand Up @@ -1028,8 +1060,20 @@ class MockXMLHttpRequest {
MockXMLHttpRequest.requests.push(this);
}

timeout: number;

send(data: any): void {
this.data = data;
if (this.timeout && this.timeout > 0) {
setTimeout(() => {
if (this.readyState != 4) {
this.readyState = 4;
this.status = 0;
this.triggerEvent('readystatechange');
this.triggerEvent('timeout');
}
}, this.timeout);
}
}

open(method: any, url: any, async: any, user: any, password: any): void {
Expand All @@ -1039,7 +1083,7 @@ class MockXMLHttpRequest {
this.user = user;
this.password = password;
this.readyState = 1;
this.triggerEvent('readyStateChange');
this.triggerEvent('readystatechange');
const originalProgressHandler = this.upload.onprogress;
Object.defineProperty(this.upload, 'progress', {
get() {
Expand All @@ -1052,24 +1096,6 @@ class MockXMLHttpRequest {
this.requestHeaders[key] = value;
}

addEventListener(name: string, handler: any): void {
this.eventHandlers.push({ name: name, handler: handler });
}

removeEventListener(name: string, handler: any): void {
for (let i = this.eventHandlers.length - 1; i--; ) {
let eh = this.eventHandlers[i];
if (eh.name === name && eh.handler === handler) {
this.eventHandlers.splice(i, 1);
}
}
}

throwError(err: any): void {
// TODO: something better with errors
this.triggerEvent('error');
}

protected jsonResponseValue(response: any) {
try {
this.response = JSON.parse(response.responseText);
Expand Down Expand Up @@ -1117,17 +1143,11 @@ class MockXMLHttpRequest {

triggerEvent(name: any, eventObj?: any): void {
// TODO: create a better default event
const e: any = eventObj || {};
const e: any = eventObj || { type: name };

if (this['on' + name]) {
this['on' + name](e);
}

this.eventHandlers.forEach(function (eh) {
if (eh.name === name) {
eh.handler.call(this, e);
}
});
}

triggerUploadEvent(name: any, eventObj?: any): void {
Expand Down
18 changes: 13 additions & 5 deletions src/internal/observable/dom/AjaxObservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,15 @@ export class AjaxSubscriber<T> extends Subscriber<Event> {
}

function xhrReadyStateChange(this: XMLHttpRequest, e: Event) {
const { subscriber, progressSubscriber, request } = (<any>xhrReadyStateChange);
return;
}
xhr.onreadystatechange = xhrReadyStateChange;
(<any>xhrReadyStateChange).subscriber = this;
(<any>xhrReadyStateChange).progressSubscriber = progressSubscriber;
(<any>xhrReadyStateChange).request = request;

function xhrLoad(this: XMLHttpRequest, e: Event) {
const { subscriber, progressSubscriber, request } = (<any>xhrLoad);
if (this.readyState === 4) {
// normalize IE9 bug (http://bugs.jquery.com/ticket/1450)
let status: number = this.status === 1223 ? 204 : this.status;
Expand Down Expand Up @@ -382,10 +390,10 @@ export class AjaxSubscriber<T> extends Subscriber<Event> {
}
}
}
xhr.onreadystatechange = xhrReadyStateChange;
(<any>xhrReadyStateChange).subscriber = this;
(<any>xhrReadyStateChange).progressSubscriber = progressSubscriber;
(<any>xhrReadyStateChange).request = request;
xhr.onload = xhrLoad;
(<any>xhrLoad).subscriber = this;
(<any>xhrLoad).progressSubscriber = progressSubscriber;
(<any>xhrLoad).request = request;
}

unsubscribe() {
Expand Down

0 comments on commit 8bab826

Please sign in to comment.