mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(core): Validate node name when creating NodeOperationErrror
(#11999)
This commit is contained in:
parent
0ffc8591a0
commit
e68c9da30c
43
packages/cli/src/__tests__/object-to-error.test.ts
Normal file
43
packages/cli/src/__tests__/object-to-error.test.ts
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import { mock } from 'jest-mock-extended';
|
||||||
|
import type { INode } from 'n8n-workflow';
|
||||||
|
import { NodeOperationError, type Workflow } from 'n8n-workflow';
|
||||||
|
|
||||||
|
import { objectToError } from '../workflow-execute-additional-data';
|
||||||
|
|
||||||
|
describe('objectToError', () => {
|
||||||
|
describe('node error handling', () => {
|
||||||
|
it('should create `NodeOperationError` when node is found', () => {
|
||||||
|
const errorObject = {
|
||||||
|
message: 'Test error',
|
||||||
|
node: {
|
||||||
|
name: 'testNode',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const workflow = mock<Workflow>();
|
||||||
|
const node = mock<INode>();
|
||||||
|
workflow.getNode.mockReturnValue(node);
|
||||||
|
|
||||||
|
const result = objectToError(errorObject, workflow);
|
||||||
|
|
||||||
|
expect(workflow.getNode).toHaveBeenCalledWith('testNode');
|
||||||
|
expect(result).toBeInstanceOf(NodeOperationError);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create `Error` when node is not found', () => {
|
||||||
|
const errorObject = {
|
||||||
|
message: 'Test error',
|
||||||
|
node: {
|
||||||
|
// missing `name`
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const workflow = mock<Workflow>();
|
||||||
|
|
||||||
|
const result = objectToError(errorObject, workflow);
|
||||||
|
|
||||||
|
expect(workflow.getNode).not.toHaveBeenCalled();
|
||||||
|
expect(result).toBeInstanceOf(Error);
|
||||||
|
expect(result).not.toBeInstanceOf(NodeOperationError);
|
||||||
|
expect(result.message).toBe('Test error');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -58,7 +58,7 @@ export function isStringArray(value: unknown): value is string[] {
|
||||||
|
|
||||||
export const isIntegerString = (value: string) => /^\d+$/.test(value);
|
export const isIntegerString = (value: string) => /^\d+$/.test(value);
|
||||||
|
|
||||||
export function isObjectLiteral(item: unknown): item is { [key: string]: string } {
|
export function isObjectLiteral(item: unknown): item is { [key: string]: unknown } {
|
||||||
return typeof item === 'object' && item !== null && !Array.isArray(item);
|
return typeof item === 'object' && item !== null && !Array.isArray(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ import type { IWorkflowErrorData, UpdateExecutionPayload } from '@/interfaces';
|
||||||
import { NodeTypes } from '@/node-types';
|
import { NodeTypes } from '@/node-types';
|
||||||
import { Push } from '@/push';
|
import { Push } from '@/push';
|
||||||
import { WorkflowStatisticsService } from '@/services/workflow-statistics.service';
|
import { WorkflowStatisticsService } from '@/services/workflow-statistics.service';
|
||||||
import { findSubworkflowStart, isWorkflowIdValid } from '@/utils';
|
import { findSubworkflowStart, isObjectLiteral, isWorkflowIdValid } from '@/utils';
|
||||||
import * as WorkflowHelpers from '@/workflow-helpers';
|
import * as WorkflowHelpers from '@/workflow-helpers';
|
||||||
|
|
||||||
import { WorkflowRepository } from './databases/repositories/workflow.repository';
|
import { WorkflowRepository } from './databases/repositories/workflow.repository';
|
||||||
|
@ -80,11 +80,20 @@ export function objectToError(errorObject: unknown, workflow: Workflow): Error {
|
||||||
if (errorObject instanceof Error) {
|
if (errorObject instanceof Error) {
|
||||||
// If it's already an Error instance, return it as is.
|
// If it's already an Error instance, return it as is.
|
||||||
return errorObject;
|
return errorObject;
|
||||||
} else if (errorObject && typeof errorObject === 'object' && 'message' in errorObject) {
|
} else if (
|
||||||
|
isObjectLiteral(errorObject) &&
|
||||||
|
'message' in errorObject &&
|
||||||
|
typeof errorObject.message === 'string'
|
||||||
|
) {
|
||||||
// If it's an object with a 'message' property, create a new Error instance.
|
// If it's an object with a 'message' property, create a new Error instance.
|
||||||
let error: Error | undefined;
|
let error: Error | undefined;
|
||||||
if ('node' in errorObject) {
|
if (
|
||||||
const node = workflow.getNode((errorObject.node as { name: string }).name);
|
'node' in errorObject &&
|
||||||
|
isObjectLiteral(errorObject.node) &&
|
||||||
|
typeof errorObject.node.name === 'string'
|
||||||
|
) {
|
||||||
|
const node = workflow.getNode(errorObject.node.name);
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
error = new NodeOperationError(
|
error = new NodeOperationError(
|
||||||
node,
|
node,
|
||||||
|
@ -95,7 +104,7 @@ export function objectToError(errorObject: unknown, workflow: Workflow): Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error === undefined) {
|
if (error === undefined) {
|
||||||
error = new Error(errorObject.message as string);
|
error = new Error(errorObject.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('description' in errorObject) {
|
if ('description' in errorObject) {
|
||||||
|
|
Loading…
Reference in a new issue