diff --git a/packages/cli/src/ActiveWebhooks.ts b/packages/cli/src/ActiveWebhooks.ts index b594a1b795070..a271021471412 100644 --- a/packages/cli/src/ActiveWebhooks.ts +++ b/packages/cli/src/ActiveWebhooks.ts @@ -6,7 +6,7 @@ import type { WorkflowActivateMode, WorkflowExecuteMode, } from 'n8n-workflow'; - +import { WebhookPathAlreadyTakenError } from 'n8n-workflow'; import * as NodeExecuteFunctions from 'n8n-core'; @Service() @@ -46,9 +46,7 @@ export class ActiveWebhooks { // check that there is not a webhook already registered with that path/method if (this.webhookUrls[webhookKey] && !webhookData.webhookId) { - throw new Error( - `The URL path that the "${webhookData.node}" node uses is already taken. Please change it to something else.`, - ); + throw new WebhookPathAlreadyTakenError(webhookData.node); } if (this.workflowWebhooks[webhookData.workflowId] === undefined) { diff --git a/packages/cli/src/ActiveWorkflowRunner.ts b/packages/cli/src/ActiveWorkflowRunner.ts index f60b3ffcdb28f..e6bd6b9f5c528 100644 --- a/packages/cli/src/ActiveWorkflowRunner.ts +++ b/packages/cli/src/ActiveWorkflowRunner.ts @@ -29,6 +29,7 @@ import { WorkflowActivationError, LoggerProxy as Logger, ErrorReporterProxy as ErrorReporter, + WebhookPathAlreadyTakenError, } from 'n8n-workflow'; import type express from 'express'; @@ -428,11 +429,8 @@ export class ActiveWorkflowRunner implements IWebhookManager { // if it's a workflow from the the insert // TODO check if there is standard error code for duplicate key violation that works // with all databases - if (error.name === 'QueryFailedError') { - error = new Error( - `The URL path that the "${webhook.node}" node uses is already taken. Please change it to something else.`, - { cause: error }, - ); + if (error instanceof Error && error.name === 'QueryFailedError') { + error = new WebhookPathAlreadyTakenError(webhook.node, error); } else if (error.detail) { // it's a error running the webhook methods (checkExists, create) error.message = error.detail; diff --git a/packages/cli/src/ErrorReporting.ts b/packages/cli/src/ErrorReporting.ts index b12a19f95e726..e850b6e4faac7 100644 --- a/packages/cli/src/ErrorReporting.ts +++ b/packages/cli/src/ErrorReporting.ts @@ -1,6 +1,6 @@ import { createHash } from 'crypto'; import config from '@/config'; -import { ErrorReporterProxy, NodeError } from 'n8n-workflow'; +import { ErrorReporterProxy, ExecutionBaseError } from 'n8n-workflow'; let initialized = false; @@ -39,7 +39,7 @@ export const initErrorHandling = async () => { const seenErrors = new Set(); addGlobalEventProcessor((event, { originalException }) => { - if (originalException instanceof NodeError && originalException.severity === 'warning') + if (originalException instanceof ExecutionBaseError && originalException.severity === 'warning') return null; if (!event.exception) return null; const eventHash = createHash('sha1').update(JSON.stringify(event.exception)).digest('base64'); diff --git a/packages/workflow/src/NodeErrors.ts b/packages/workflow/src/NodeErrors.ts index 302d9f12a8f24..a78bd2af6cf33 100644 --- a/packages/workflow/src/NodeErrors.ts +++ b/packages/workflow/src/NodeErrors.ts @@ -104,7 +104,7 @@ const STATUS_CODE_MESSAGES: IStatusCodeMessages = { const UNKNOWN_ERROR_MESSAGE = 'UNKNOWN ERROR - check the detailed error for more information'; const UNKNOWN_ERROR_MESSAGE_CRED = 'UNKNOWN ERROR'; -type Severity = 'warning' | 'error'; +export type Severity = 'warning' | 'error'; interface ExecutionBaseErrorOptions { cause?: Error | JsonObject; @@ -136,6 +136,8 @@ export abstract class ExecutionBaseError extends Error { lineNumber: number | undefined; + severity: Severity = 'error'; + constructor(message: string, { cause }: ExecutionBaseErrorOptions) { const options = cause instanceof Error ? { cause } : {}; super(message, options); @@ -171,8 +173,6 @@ export abstract class ExecutionBaseError extends Error { export abstract class NodeError extends ExecutionBaseError { node: INode; - severity: Severity = 'error'; - constructor(node: INode, error: Error | JsonObject) { const message = error instanceof Error ? error.message : ''; super(message, { cause: error }); diff --git a/packages/workflow/src/WorkflowActivationError.ts b/packages/workflow/src/WorkflowActivationError.ts index dd1ba2c42223c..d9a7943a99e0c 100644 --- a/packages/workflow/src/WorkflowActivationError.ts +++ b/packages/workflow/src/WorkflowActivationError.ts @@ -1,9 +1,10 @@ import type { INode } from './Interfaces'; -import { ExecutionBaseError } from './NodeErrors'; +import { ExecutionBaseError, type Severity } from './NodeErrors'; interface WorkflowActivationErrorOptions { cause?: Error; node?: INode; + severity?: Severity; } /** @@ -12,7 +13,7 @@ interface WorkflowActivationErrorOptions { export class WorkflowActivationError extends ExecutionBaseError { node: INode | undefined; - constructor(message: string, { cause, node }: WorkflowActivationErrorOptions) { + constructor(message: string, { cause, node, severity }: WorkflowActivationErrorOptions) { let error = cause as Error; if (cause instanceof ExecutionBaseError) { error = new Error(cause.message); @@ -23,5 +24,15 @@ export class WorkflowActivationError extends ExecutionBaseError { super(message, { cause: error }); this.node = node; this.message = message; + if (severity) this.severity = severity; + } +} + +export class WebhookPathAlreadyTakenError extends WorkflowActivationError { + constructor(nodeName: string, cause?: Error) { + super( + `The URL path that the "${nodeName}" node uses is already taken. Please change it to something else.`, + { severity: 'warning', cause }, + ); } }