From a3b246c9de5c3bc4b5a742e15add55b375479451 Mon Sep 17 00:00:00 2001 From: Dmitriy Mozgovoy Date: Wed, 22 Feb 2023 21:50:31 +0200 Subject: [PATCH] fix(http): fixed regression bug when handling synchronous errors inside the adapter; (#5564) --- lib/adapters/http.js | 58 ++++++++++++++++++++++---------------- package.json | 2 +- test/unit/adapters/http.js | 4 +++ 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/lib/adapters/http.js b/lib/adapters/http.js index b309481cf5..9ca70668e9 100755 --- a/lib/adapters/http.js +++ b/lib/adapters/http.js @@ -116,15 +116,39 @@ function setProxy(options, configProxy, location) { const isHttpAdapterSupported = typeof process !== 'undefined' && utils.kindOf(process) === 'process'; +// temporary hotfix + +const wrapAsync = (asyncExecutor) => { + return new Promise((resolve, reject) => { + let onDone; + let isDone; + + const done = (value, isRejected) => { + if (isDone) return; + isDone = true; + onDone && onDone(value, isRejected); + } + + const _resolve = (value) => { + done(value); + resolve(value); + }; + + const _reject = (reason) => { + done(reason, true); + reject(reason); + } + + asyncExecutor(_resolve, _reject, (onDoneHandler) => (onDone = onDoneHandler)).catch(_reject); + }) +}; + /*eslint consistent-return:0*/ export default isHttpAdapterSupported && function httpAdapter(config) { - /*eslint no-async-promise-executor:0*/ - return new Promise(async function dispatchHttpRequest(resolvePromise, rejectPromise) { - let data = config.data; - const responseType = config.responseType; - const responseEncoding = config.responseEncoding; + return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) { + let {data} = config; + const {responseType, responseEncoding} = config; const method = config.method.toUpperCase(); - let isFinished; let isDone; let rejected = false; let req; @@ -132,10 +156,7 @@ export default isHttpAdapterSupported && function httpAdapter(config) { // temporary internal emitter until the AxiosRequest class will be implemented const emitter = new EventEmitter(); - function onFinished() { - if (isFinished) return; - isFinished = true; - + const onFinished = () => { if (config.cancelToken) { config.cancelToken.unsubscribe(abort); } @@ -147,26 +168,13 @@ export default isHttpAdapterSupported && function httpAdapter(config) { emitter.removeAllListeners(); } - function done(value, isRejected) { - if (isDone) return; - + onDone((value, isRejected) => { isDone = true; - if (isRejected) { rejected = true; onFinished(); } - - isRejected ? rejectPromise(value) : resolvePromise(value); - } - - const resolve = function resolve(value) { - done(value); - }; - - const reject = function reject(value) { - done(value, true); - }; + }); function abort(reason) { emitter.emit('abort', !reason || reason.type ? new CanceledError(null, config, req) : reason); diff --git a/package.json b/package.json index f5087f15e5..2dba9215ce 100644 --- a/package.json +++ b/package.json @@ -203,4 +203,4 @@ "@commitlint/config-conventional" ] } -} \ No newline at end of file +} diff --git a/test/unit/adapters/http.js b/test/unit/adapters/http.js index 5b500f957e..5d6620abc3 100644 --- a/test/unit/adapters/http.js +++ b/test/unit/adapters/http.js @@ -2099,4 +2099,8 @@ describe('supports http with nodejs', function () { } }); }) + + it('should properly handle synchronous errors inside the adapter', function () { + return assert.rejects(() => axios.get('http://192.168.0.285'), /Invalid URL/); + }); });