diff --git a/lib/XMLHttpRequest.js b/lib/XMLHttpRequest.js index f37edf02..45525f8a 100644 --- a/lib/XMLHttpRequest.js +++ b/lib/XMLHttpRequest.js @@ -859,11 +859,14 @@ function XMLHttpRequest(opts) { } // Error handler for the request - var errorHandler = function(error) { + var errorHandler = function(error, associatedRequest) { // In the case of https://nodejs.org/api/http.html#requestreusedsocket triggering an ECONNRESET, // don't fail the xhr request, attempt again. - if (request.reusedSocket && error.code === 'ECONNRESET') - return doRequest(options, responseHandler).on('error', errorHandler); + if (associatedRequest.reusedSocket && error.code === 'ECONNRESET') + { + const retryRequest = doRequest(options, responseHandler) + retryRequest.on('error', (error) => errorHandler(error, retryRequest)); + } handleError(error); } @@ -871,7 +874,8 @@ function XMLHttpRequest(opts) { opt = Object.assign(Object.create(null), opt); if (isSsl) Object.assign(opt, sslOptions); - request = doRequest(opt, responseHandler).on('error', errorHandler); + const httpRequest = doRequest(opt, responseHandler); + request = httpRequest.on('error', (error) => errorHandler(error, httpRequest)); if (opts.autoUnref) { request.on('socket', function (socket) { diff --git a/tests/abort-request.js b/tests/abort-request.js new file mode 100644 index 00000000..634e08fb --- /dev/null +++ b/tests/abort-request.js @@ -0,0 +1,41 @@ +'use strict'; + +const http = require('http'); +const XHR = require('../lib/XMLHttpRequest').XMLHttpRequest; + +process.on('uncaughtException', (e) => { console.error('uncaught: ', e); process.exitCode = 1; }); +process.on('unhandledRejection', (e) => { console.error('unhandled: ', e); process.exitCode = 2; }); + +const server = http.createServer((req, res) => { + // never respond to requests - simulate slow server for the abort +}); + +server.listen(0, '127.0.0.1', () => { + requestAndAbort(); +}); + +function requestAndAbort() { + const url = new URL(`http://127.0.0.1:${server.address().port}`); + const xhr = new XHR(); + + xhr.open('GET', url); + xhr.send(); + + setTimeout(() => { + console.log('calling abort'); + try { + xhr.abort() + } + catch (e) { + console.error('abort threw:', e); + process.exitCode = 3; + } + console.log('aborted request') + setTimeout(() => { + server.close(); + server.closeAllConnections?.(); + process.exit(); + }, 500); + + }, 200); +} \ No newline at end of file