diff --git a/packages/core/package.json b/packages/core/package.json index c029de05d47a5..c00bfb8e8931a 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -39,6 +39,7 @@ "@types/crypto-js": "^4.0.1", "@types/express": "^4.17.6", "@types/lodash.get": "^4.4.6", + "@types/lodash.pick": "^4.4.7", "@types/mime-types": "^2.1.0", "@types/request-promise-native": "~1.0.15", "@types/uuid": "^8.3.2" @@ -54,6 +55,7 @@ "flatted": "^3.2.4", "form-data": "^4.0.0", "lodash.get": "^4.4.2", + "lodash.pick": "^4.4.0", "mime-types": "^2.1.27", "n8n-workflow": "workspace:*", "oauth-1.0a": "^2.2.6", diff --git a/packages/core/src/NodeExecuteFunctions.ts b/packages/core/src/NodeExecuteFunctions.ts index b3a9e1867dafe..804c866845c3c 100644 --- a/packages/core/src/NodeExecuteFunctions.ts +++ b/packages/core/src/NodeExecuteFunctions.ts @@ -75,6 +75,7 @@ import { ExpressionError, } from 'n8n-workflow'; +import pick from 'lodash.pick'; import { Agent } from 'https'; import { stringify } from 'qs'; import type { Token } from 'oauth-1.0a'; @@ -675,50 +676,47 @@ async function proxyRequestToAxios( return body; } } catch (error) { - const { request, response, isAxiosError, toJSON, config, ...errorData } = error; - if (configObject.simple === false && response) { - if (configObject.resolveWithFullResponse) { - return { - body: response.data, - headers: response.headers, - statusCode: response.status, - statusMessage: response.statusText, - }; - } else { - return response.data; - } - } + const { config, response } = error; // Axios hydrates the original error with more data. We extract them. // https://github.com/axios/axios/blob/master/lib/core/enhanceError.js // Note: `code` is ignored as it's an expected part of the errorData. - if (response) { - Logger.debug('Request proxied to Axios failed', { status: response.status }); - let responseData = response.data; + if (error.isAxiosError) { + if (response) { + Logger.debug('Request proxied to Axios failed', { status: response.status }); + let responseData = response.data; + + if (Buffer.isBuffer(responseData) || responseData instanceof Readable) { + responseData = await binaryToBuffer(responseData).then((buffer) => + buffer.toString('utf-8'), + ); + } - if (Buffer.isBuffer(responseData) || responseData instanceof Readable) { - responseData = await binaryToBuffer(responseData).then((buffer) => - buffer.toString('utf-8'), - ); + if (configObject.simple === false) { + if (configObject.resolveWithFullResponse) { + return { + body: responseData, + headers: response.headers, + statusCode: response.status, + statusMessage: response.statusText, + }; + } else { + return responseData; + } + } + + const message = `${response.status as number} - ${JSON.stringify(responseData)}`; + throw Object.assign(new Error(message, { cause: error }), { + statusCode: response.status, + options: pick(config ?? {}, ['url', 'method', 'data', 'headers']), + }); + } else { + throw Object.assign(new Error(error.message, { cause: error }), { + options: pick(config ?? {}, ['url', 'method', 'data', 'headers']), + }); } - error.message = `${response.status as number} - ${JSON.stringify(responseData)}`; } - error.cause = errorData; - error.error = error.response?.data || errorData; - error.statusCode = error.response?.status; - error.options = config || {}; - - // Remove not needed data and so also remove circular references - error.request = undefined; - error.config = undefined; - error.options.adapter = undefined; - error.options.httpsAgent = undefined; - error.options.paramsSerializer = undefined; - error.options.transformRequest = undefined; - error.options.transformResponse = undefined; - error.options.validateStatus = undefined; - throw error; } } diff --git a/packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts b/packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts index 6c0b327f6090d..880df2466124d 100644 --- a/packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts +++ b/packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts @@ -1321,7 +1321,7 @@ export class HttpRequestV3 implements INodeType { if (autoDetectResponseFormat && response.reason.error instanceof Buffer) { response.reason.error = Buffer.from(response.reason.error as Buffer).toString(); } - throw new NodeApiError(this.getNode(), response as JsonObject); + throw new NodeApiError(this.getNode(), response.reason as JsonObject); } else { // Return the actual reason as error returnItems.push({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5c8c4876a9af1..e1355406661e2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -613,6 +613,9 @@ importers: lodash.get: specifier: ^4.4.2 version: 4.4.2 + lodash.pick: + specifier: ^4.4.0 + version: 4.4.0 mime-types: specifier: ^2.1.27 version: 2.1.35 @@ -656,6 +659,9 @@ importers: '@types/lodash.get': specifier: ^4.4.6 version: 4.4.7 + '@types/lodash.pick': + specifier: ^4.4.7 + version: 4.4.7 '@types/mime-types': specifier: ^2.1.0 version: 2.1.1 @@ -4772,7 +4778,7 @@ packages: '@storybook/csf-plugin': 7.0.0-beta.46 '@storybook/csf-tools': 7.0.0-beta.46 '@storybook/global': 5.0.0 - '@storybook/mdx2-csf': 1.0.0-next.7 + '@storybook/mdx2-csf': 1.0.0-next.8 '@storybook/node-logger': 7.0.0-beta.46 '@storybook/postinstall': 7.0.0-beta.46 '@storybook/preview-api': 7.0.0-beta.46 @@ -5379,7 +5385,7 @@ packages: '@storybook/core-events': 7.0.0-beta.46 '@storybook/csf': 0.0.2-next.11 '@storybook/csf-tools': 7.0.0-beta.46 - '@storybook/docs-mdx': 0.0.1-next.6 + '@storybook/docs-mdx': 0.0.1-next.7 '@storybook/global': 5.0.0 '@storybook/manager': 7.0.0-beta.46 '@storybook/node-logger': 7.0.0-beta.46 @@ -5468,8 +5474,8 @@ packages: type-fest: 2.19.0 dev: true - /@storybook/docs-mdx@0.0.1-next.6: - resolution: {integrity: sha512-DjoSIXADmLJtdroXAjUotFiZlcZ2usWhqrS7aeOtZs0DVR0Ws5WQjnwtpDUXt8gryTSd+OZJ0cNsDcqg4JDEvQ==} + /@storybook/docs-mdx@0.0.1-next.7: + resolution: {integrity: sha512-JbgBf/EMBtx65iXtB3pOiX3818UeL9jZ+KAY241OAPqJVXjMQ5KaVOdg/57MSmd508HDIGx7CiImOMEmWwQ9/g==} dev: true /@storybook/docs-tools@7.0.0-beta.46: @@ -5521,8 +5527,8 @@ packages: resolution: {integrity: sha512-0Tsm47YM3SU9rvPpXxp6/toQ1DDUrIbZt1pXcj72szLZvi7U/fXTMpsBX9gOB1MNVYIYRqS2V+jcO8UjFd4qyQ==} dev: true - /@storybook/mdx2-csf@1.0.0-next.7: - resolution: {integrity: sha512-xcQ8w4IecABAjsakaZTGiUEnEgFZzVKsMjqECjd+qdkwgD3R/kwrBdfyC15CLM5Ye1miPwYBIwJGeBXB9qxsZg==} + /@storybook/mdx2-csf@1.0.0-next.8: + resolution: {integrity: sha512-t2O5s/HHTH5evZVHgVtCWTZgMZ/CaqDu3xVGgjVbKeTvpPAbi0Waab5SSX8T9PG5jNDei/x+jpAVCcNMOHoWzg==} dev: true /@storybook/node-logger@6.5.15: