From b1de0c6b6f99749c303f678f3666d7860a92a9af Mon Sep 17 00:00:00 2001 From: Henry Date: Fri, 20 Jun 2025 10:44:58 +0100 Subject: [PATCH] Enhancement: Add JSON sanitization and parsing methods to HTTP agentflow. - Introduced `sanitizeJsonString` to clean problematic escape sequences and fix common JSON formatting issues. - Added `parseJsonBody` to attempt parsing JSON directly, with fallback to sanitization if parsing fails, providing clearer error messages for invalid JSON. - Updated request handling to utilize the new parsing method for JSON and x-www-form-urlencoded body types. --- .../components/nodes/agentflow/HTTP/HTTP.ts | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/packages/components/nodes/agentflow/HTTP/HTTP.ts b/packages/components/nodes/agentflow/HTTP/HTTP.ts index 9c3234055..067cf9bfc 100644 --- a/packages/components/nodes/agentflow/HTTP/HTTP.ts +++ b/packages/components/nodes/agentflow/HTTP/HTTP.ts @@ -18,6 +18,37 @@ class HTTP_Agentflow implements INode { credential: INodeParams inputs: INodeParams[] + private sanitizeJsonString(jsonString: string): string { + // Remove common problematic escape sequences that are not valid JSON + let sanitized = jsonString + // Remove escaped square brackets (not valid JSON) + .replace(/\\(\[|\])/g, '$1') + // Fix unquoted string values in JSON (simple case) + .replace(/:\s*([a-zA-Z][a-zA-Z0-9]*)\s*([,}])/g, ': "$1"$2') + // Fix trailing commas + .replace(/,(\s*[}\]])/g, '$1') + + return sanitized + } + + private parseJsonBody(body: string): any { + try { + // First try to parse as-is + return JSON.parse(body) + } catch (error) { + try { + // If that fails, try to sanitize and parse + const sanitized = this.sanitizeJsonString(body) + return JSON.parse(sanitized) + } catch (sanitizeError) { + // If sanitization also fails, throw the original error with helpful message + throw new Error( + `Invalid JSON format in body. Original error: ${error.message}. Please ensure your JSON is properly formatted with quoted strings and valid escape sequences.` + ) + } + } + } + constructor() { this.label = 'HTTP' this.name = 'httpAgentflow' @@ -272,10 +303,11 @@ class HTTP_Agentflow implements INode { // Handle request body based on body type if (method !== 'GET' && body) { switch (bodyType) { - case 'json': - requestConfig.data = typeof body === 'string' ? JSON.parse(body) : body + case 'json': { + requestConfig.data = typeof body === 'string' ? this.parseJsonBody(body) : body requestHeaders['Content-Type'] = 'application/json' break + } case 'raw': requestConfig.data = body break @@ -290,7 +322,7 @@ class HTTP_Agentflow implements INode { break } case 'xWwwFormUrlencoded': - requestConfig.data = querystring.stringify(typeof body === 'string' ? JSON.parse(body) : body) + requestConfig.data = querystring.stringify(typeof body === 'string' ? this.parseJsonBody(body) : body) requestHeaders['Content-Type'] = 'application/x-www-form-urlencoded' break }