fix(HTTP Request Tool Node): Respond with an error when receive binary response (#11219)

This commit is contained in:
Eugene
2024-10-11 17:12:03 +02:00
committed by GitHub
parent 8734dc99fc
commit 0d23a7fb5b
5 changed files with 212 additions and 22 deletions

View File

@@ -1,3 +1,12 @@
import { Readability } from '@mozilla/readability';
import cheerio from 'cheerio';
import { convert } from 'html-to-text';
import { JSDOM } from 'jsdom';
import get from 'lodash/get';
import set from 'lodash/set';
import unset from 'lodash/unset';
import * as mime from 'mime-types';
import { getOAuth2AdditionalParameters } from 'n8n-nodes-base/dist/nodes/HttpRequest/GenericFunctions';
import type {
IExecuteFunctions,
IDataObject,
@@ -7,20 +16,8 @@ import type {
NodeApiError,
} from 'n8n-workflow';
import { NodeConnectionType, NodeOperationError, jsonParse } from 'n8n-workflow';
import { getOAuth2AdditionalParameters } from 'n8n-nodes-base/dist/nodes/HttpRequest/GenericFunctions';
import set from 'lodash/set';
import get from 'lodash/get';
import unset from 'lodash/unset';
import cheerio from 'cheerio';
import { convert } from 'html-to-text';
import { Readability } from '@mozilla/readability';
import { JSDOM } from 'jsdom';
import { z } from 'zod';
import type { DynamicZodObject } from '../../../types/zod.types';
import type {
ParameterInputType,
ParametersValues,
@@ -29,6 +26,7 @@ import type {
SendIn,
ToolParameter,
} from './interfaces';
import type { DynamicZodObject } from '../../../types/zod.types';
const genericCredentialRequest = async (ctx: IExecuteFunctions, itemIndex: number) => {
const genericType = ctx.getNodeParameter('genericAuthType', itemIndex) as string;
@@ -176,6 +174,7 @@ const htmlOptimizer = (ctx: IExecuteFunctions, itemIndex: number, maxLength: num
);
}
const returnData: string[] = [];
const html = cheerio.load(response);
const htmlElements = html(cssSelector);
@@ -574,6 +573,7 @@ export const configureToolFunction = (
// Clone options and rawRequestOptions to avoid mutating the original objects
const options: IHttpRequestOptions | null = structuredClone(requestOptions);
const clonedRawRequestOptions: { [key: string]: string } = structuredClone(rawRequestOptions);
let fullResponse: any;
let response: string = '';
let executionError: Error | undefined = undefined;
@@ -732,8 +732,6 @@ export const configureToolFunction = (
}
}
} catch (error) {
console.error(error);
const errorMessage = 'Input provided by model is not valid';
if (error instanceof NodeOperationError) {
@@ -749,11 +747,29 @@ export const configureToolFunction = (
if (options) {
try {
response = optimizeResponse(await httpRequest(options));
fullResponse = await httpRequest(options);
} catch (error) {
const httpCode = (error as NodeApiError).httpCode;
response = `${httpCode ? `HTTP ${httpCode} ` : ''}There was an error: "${error.message}"`;
}
if (!response) {
try {
// Check if the response is binary data
if (fullResponse?.headers?.['content-type']) {
const contentType = fullResponse.headers['content-type'] as string;
const mimeType = contentType.split(';')[0].trim();
if (mime.charset(mimeType) !== 'UTF-8') {
throw new NodeOperationError(ctx.getNode(), 'Binary data is not supported');
}
}
response = optimizeResponse(fullResponse.body);
} catch (error) {
response = `There was an error: "${error.message}"`;
}
}
}
if (typeof response !== 'string') {