diff --git a/lib/adapters/xhr.js b/lib/adapters/xhr.js index 81364bd56b1a00edab5768c1f7578f7426e6ad66..d0d6902064cd63ece7e090b853010366219f3bb4 100644 --- a/lib/adapters/xhr.js +++ b/lib/adapters/xhr.js @@ -80,6 +80,18 @@ module.exports = function xhrAdapter(config) { request = null; }; + // Handle browser request cancellation (as opposed to a manual cancellation) + request.onabort = function handleAbort() { + if (!request) { + return; + } + + reject(createError('Request aborted', config, 'ECONNABORTED', request)); + + // Clean up request + request = null; + }; + // Handle low level network errors request.onerror = function handleError() { // Real errors are hidden from us by the browser diff --git a/test/specs/requests.spec.js b/test/specs/requests.spec.js index 0a272b67ad1e61e2d0959b59d6e7502075423b2d..6acc4f3865291f265c6b668c0b9572860f388b57 100644 --- a/test/specs/requests.spec.js +++ b/test/specs/requests.spec.js @@ -79,6 +79,31 @@ describe('requests', function () { .then(finish, finish); }); + it('should reject on abort', function (done) { + var resolveSpy = jasmine.createSpy('resolve'); + var rejectSpy = jasmine.createSpy('reject'); + + var finish = function () { + expect(resolveSpy).not.toHaveBeenCalled(); + expect(rejectSpy).toHaveBeenCalled(); + var reason = rejectSpy.calls.first().args[0]; + expect(reason instanceof Error).toBe(true); + expect(reason.config.method).toBe('get'); + expect(reason.config.url).toBe('/foo'); + expect(reason.request).toEqual(jasmine.any(XMLHttpRequest)); + + done(); + }; + + axios('/foo') + .then(resolveSpy, rejectSpy) + .then(finish, finish); + + getAjaxRequest().then(function (request) { + request.abort(); + }); + }); + it('should reject when validateStatus returns false', function (done) { var resolveSpy = jasmine.createSpy('resolve'); var rejectSpy = jasmine.createSpy('reject');