From 4773aad170d6bf903d6d2db561804aba66dec0bf Mon Sep 17 00:00:00 2001 From: Michael Kret <88898367+michael-radency@users.noreply.github.com> Date: Thu, 27 Jun 2024 13:22:07 +0300 Subject: [PATCH] fix: Error processing and output pane improvements (no-changelog) (#9626) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ --- .../src/components/Error/NodeErrorView.vue | 1 + .../nodes-base/nodes/Cal/GenericFunctions.ts | 1 - packages/nodes-base/nodes/Coda/Coda.node.ts | 2 -- .../nodes/GetResponse/GetResponse.node.ts | 5 ++++ .../nodes/Google/Drive/v2/transport/index.ts | 2 -- .../HttpRequest/V3/HttpRequestV3.node.ts | 14 ++++++++- .../nodes/UProc/GenericFunctions.ts | 1 - .../src/errors/abstract/node.error.ts | 13 ++++++-- .../workflow/src/errors/node-api.error.ts | 30 +++++++++++-------- 9 files changed, 47 insertions(+), 22 deletions(-) diff --git a/packages/editor-ui/src/components/Error/NodeErrorView.vue b/packages/editor-ui/src/components/Error/NodeErrorView.vue index d954fd9543..5244371d0f 100644 --- a/packages/editor-ui/src/components/Error/NodeErrorView.vue +++ b/packages/editor-ui/src/components/Error/NodeErrorView.vue @@ -613,6 +613,7 @@ function copySuccess() { } &__header-description { + overflow: hidden; padding: 0 var(--spacing-s) var(--spacing-3xs) var(--spacing-s); font-size: var(--font-size-xs); diff --git a/packages/nodes-base/nodes/Cal/GenericFunctions.ts b/packages/nodes-base/nodes/Cal/GenericFunctions.ts index d1aecef364..e95eb42cfe 100644 --- a/packages/nodes-base/nodes/Cal/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Cal/GenericFunctions.ts @@ -37,7 +37,6 @@ export async function calApiRequest( try { return await this.helpers.httpRequestWithAuthentication.call(this, 'calApi', options); } catch (error) { - if (error instanceof NodeApiError) throw error; throw new NodeApiError(this.getNode(), error as JsonObject); } } diff --git a/packages/nodes-base/nodes/Coda/Coda.node.ts b/packages/nodes-base/nodes/Coda/Coda.node.ts index 0ea60670e5..be5bf1a796 100644 --- a/packages/nodes-base/nodes/Coda/Coda.node.ts +++ b/packages/nodes-base/nodes/Coda/Coda.node.ts @@ -435,7 +435,6 @@ export class Coda implements INodeType { }); continue; } - if (error instanceof NodeApiError) throw error; throw new NodeApiError(this.getNode(), error as JsonObject); } } @@ -803,7 +802,6 @@ export class Coda implements INodeType { }); continue; } - if (error instanceof NodeApiError) throw error; throw new NodeApiError(this.getNode(), error as JsonObject); } } diff --git a/packages/nodes-base/nodes/GetResponse/GetResponse.node.ts b/packages/nodes-base/nodes/GetResponse/GetResponse.node.ts index ca4f643de2..db6636bd61 100644 --- a/packages/nodes-base/nodes/GetResponse/GetResponse.node.ts +++ b/packages/nodes-base/nodes/GetResponse/GetResponse.node.ts @@ -276,6 +276,11 @@ export class GetResponse implements INodeType { if (updateFields.customFieldsUi) { const customFieldValues = (updateFields.customFieldsUi as IDataObject) .customFieldValues as IDataObject[]; + customFieldValues.forEach((entry) => { + if (typeof entry.value === 'string') { + entry.value = entry.value.split(',').map((value) => value.trim()); + } + }); if (customFieldValues) { body.customFieldValues = customFieldValues; delete body.customFieldsUi; diff --git a/packages/nodes-base/nodes/Google/Drive/v2/transport/index.ts b/packages/nodes-base/nodes/Google/Drive/v2/transport/index.ts index b0d984f529..13d20a99ac 100644 --- a/packages/nodes-base/nodes/Google/Drive/v2/transport/index.ts +++ b/packages/nodes-base/nodes/Google/Drive/v2/transport/index.ts @@ -57,8 +57,6 @@ export async function googleApiRequest( ); } } catch (error) { - if (error instanceof NodeApiError) throw error; - if (error.code === 'ERR_OSSL_PEM_NO_START_LINE') { error.statusCode = '401'; } diff --git a/packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts b/packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts index 975353b1b0..b9b989213b 100644 --- a/packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts +++ b/packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts @@ -1869,8 +1869,20 @@ export class HttpRequestV3 implements INodeType { if (autoDetectResponseFormat && responseData.reason.error instanceof Buffer) { responseData.reason.error = Buffer.from(responseData.reason.error as Buffer).toString(); } - const error = new NodeApiError(this.getNode(), responseData as JsonObject, { itemIndex }); + + let error; + if (responseData?.reason instanceof NodeApiError) { + error = responseData.reason; + set(error, 'context.itemIndex', itemIndex); + } else { + const errorData = ( + responseData.reason ? responseData.reason : responseData + ) as JsonObject; + error = new NodeApiError(this.getNode(), errorData, { itemIndex }); + } + set(error, 'context.request', sanitizedRequests[itemIndex]); + throw error; } else { removeCircularRefs(responseData.reason as JsonObject); diff --git a/packages/nodes-base/nodes/UProc/GenericFunctions.ts b/packages/nodes-base/nodes/UProc/GenericFunctions.ts index 0575ff68fc..886522783c 100644 --- a/packages/nodes-base/nodes/UProc/GenericFunctions.ts +++ b/packages/nodes-base/nodes/UProc/GenericFunctions.ts @@ -27,7 +27,6 @@ export async function uprocApiRequest( try { return await this.helpers.httpRequestWithAuthentication.call(this, 'uprocApi', options); } catch (error) { - if (error instanceof NodeApiError) throw error; throw new NodeApiError(this.getNode(), error as JsonObject); } } diff --git a/packages/workflow/src/errors/abstract/node.error.ts b/packages/workflow/src/errors/abstract/node.error.ts index b9be7d8e95..460538fc0e 100644 --- a/packages/workflow/src/errors/abstract/node.error.ts +++ b/packages/workflow/src/errors/abstract/node.error.ts @@ -1,4 +1,4 @@ -import { isTraversableObject } from '../../utils'; +import { isTraversableObject, jsonParse } from '../../utils'; import type { IDataObject, INode, JsonObject } from '@/Interfaces'; import { ExecutionBaseError } from './execution-base.error'; @@ -81,9 +81,16 @@ export abstract class NodeError extends ExecutionBaseError { traversalKeys: string[] = [], ): string | null { for (const key of potentialKeys) { - const value = jsonError[key]; + let value = jsonError[key]; if (value) { - if (typeof value === 'string') return value; + if (typeof value === 'string') { + try { + value = jsonParse(value); + } catch (error) { + return value as string; + } + if (typeof value === 'string') return value; + } if (typeof value === 'number') return value.toString(); if (Array.isArray(value)) { const resolvedErrors: string[] = value diff --git a/packages/workflow/src/errors/node-api.error.ts b/packages/workflow/src/errors/node-api.error.ts index 781907aa26..47f231bcef 100644 --- a/packages/workflow/src/errors/node-api.error.ts +++ b/packages/workflow/src/errors/node-api.error.ts @@ -39,8 +39,9 @@ interface NodeApiErrorOptions extends NodeOperationErrorOptions { /** * Top-level properties where an error message can be found in an API response. + * order is important, precedence is from top to bottom */ -const ERROR_MESSAGE_PROPERTIES = [ +const POSSIBLE_ERROR_MESSAGE_KEYS = [ 'cause', 'error', 'message', @@ -60,6 +61,7 @@ const ERROR_MESSAGE_PROPERTIES = [ 'errorDescription', 'error_description', 'error_summary', + 'error_info', 'title', 'text', 'field', @@ -67,10 +69,15 @@ const ERROR_MESSAGE_PROPERTIES = [ 'type', ]; +/** + * Properties where a nested object can be found in an API response. + */ +const POSSIBLE_NESTED_ERROR_OBJECT_KEYS = ['Error', 'error', 'err', 'response', 'body', 'data']; + /** * Top-level properties where an HTTP error code can be found in an API response. */ -const ERROR_STATUS_PROPERTIES = [ +const POSSIBLE_ERROR_STATUS_KEYS = [ 'statusCode', 'status', 'code', @@ -79,11 +86,6 @@ const ERROR_STATUS_PROPERTIES = [ 'error_code', ]; -/** - * Properties where a nested object can be found in an API response. - */ -const ERROR_NESTING_PROPERTIES = ['error', 'err', 'response', 'body', 'data']; - /** * Descriptive messages for common HTTP status codes * this is used by NodeApiError class @@ -187,7 +189,11 @@ export class NodeApiError extends NodeError { this.httpCode = errorResponse.httpCode as string; } else { this.httpCode = - this.findProperty(errorResponse, ERROR_STATUS_PROPERTIES, ERROR_NESTING_PROPERTIES) ?? null; + this.findProperty( + errorResponse, + POSSIBLE_ERROR_STATUS_KEYS, + POSSIBLE_NESTED_ERROR_OBJECT_KEYS, + ) ?? null; } this.level = level ?? 'warning'; @@ -222,8 +228,8 @@ export class NodeApiError extends NodeError { } else { this.description = this.findProperty( errorResponse, - ERROR_MESSAGE_PROPERTIES, - ERROR_NESTING_PROPERTIES, + POSSIBLE_ERROR_MESSAGE_KEYS, + POSSIBLE_NESTED_ERROR_OBJECT_KEYS, ); } } @@ -266,8 +272,8 @@ export class NodeApiError extends NodeError { const topLevelKey = Object.keys(result)[0]; this.description = this.findProperty( result[topLevelKey], - ERROR_MESSAGE_PROPERTIES, - ['Error'].concat(ERROR_NESTING_PROPERTIES), + POSSIBLE_ERROR_MESSAGE_KEYS, + POSSIBLE_NESTED_ERROR_OBJECT_KEYS, ); }); }