Skip to content

Commit

Permalink
fix(core): Validate node name when creating NodeOperationErrror (n8…
Browse files Browse the repository at this point in the history
  • Loading branch information
ivov authored Dec 2, 2024
1 parent 0ffc859 commit e68c9da
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 6 deletions.
43 changes: 43 additions & 0 deletions packages/cli/src/__tests__/object-to-error.test.ts
Original file line number Diff line number Diff line change
@@ -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');
});
});
});
2 changes: 1 addition & 1 deletion packages/cli/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export function isStringArray(value: unknown): value is string[] {

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);
}

Expand Down
19 changes: 14 additions & 5 deletions packages/cli/src/workflow-execute-additional-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ import type { IWorkflowErrorData, UpdateExecutionPayload } from '@/interfaces';
import { NodeTypes } from '@/node-types';
import { Push } from '@/push';
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 { WorkflowRepository } from './databases/repositories/workflow.repository';
Expand Down Expand Up @@ -80,11 +80,20 @@ export function objectToError(errorObject: unknown, workflow: Workflow): Error {
if (errorObject instanceof Error) {
// If it's already an Error instance, return it as is.
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.
let error: Error | undefined;
if ('node' in errorObject) {
const node = workflow.getNode((errorObject.node as { name: string }).name);
if (
'node' in errorObject &&
isObjectLiteral(errorObject.node) &&
typeof errorObject.node.name === 'string'
) {
const node = workflow.getNode(errorObject.node.name);

if (node) {
error = new NodeOperationError(
node,
Expand All @@ -95,7 +104,7 @@ export function objectToError(errorObject: unknown, workflow: Workflow): Error {
}

if (error === undefined) {
error = new Error(errorObject.message as string);
error = new Error(errorObject.message);
}

if ('description' in errorObject) {
Expand Down

0 comments on commit e68c9da

Please sign in to comment.