mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
fix(editor): Improve sub-workflow debugging for more node error types (#14347)
This commit is contained in:
@@ -2,6 +2,11 @@ import { isObjectLiteral } from 'n8n-core';
|
||||
import { NodeOperationError } from 'n8n-workflow';
|
||||
import type { Workflow } from 'n8n-workflow';
|
||||
|
||||
/**
|
||||
* Optional properties that should be propagated from an error object to the new Error instance.
|
||||
*/
|
||||
const errorProperties = ['description', 'stack', 'executionId', 'workflowId'];
|
||||
|
||||
export function objectToError(errorObject: unknown, workflow: Workflow): Error {
|
||||
// TODO: Expand with other error types
|
||||
if (errorObject instanceof Error) {
|
||||
@@ -34,15 +39,11 @@ export function objectToError(errorObject: unknown, workflow: Workflow): Error {
|
||||
error = new Error(errorObject.message);
|
||||
}
|
||||
|
||||
if ('description' in errorObject) {
|
||||
// @ts-expect-error Error descriptions are surfaced by the UI but
|
||||
// not all backend errors account for this property yet.
|
||||
error.description = errorObject.description as string;
|
||||
}
|
||||
|
||||
if ('stack' in errorObject) {
|
||||
// If there's a 'stack' property, set it on the new Error instance.
|
||||
error.stack = errorObject.stack as string;
|
||||
for (const field of errorProperties) {
|
||||
if (field in errorObject && errorObject[field]) {
|
||||
// Not all errors contain these properties
|
||||
(error as unknown as Record<string, unknown>)[field] = errorObject[field];
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
|
||||
@@ -27,5 +27,8 @@ export function parseErrorMetadata(error: unknown): ISubWorkflowMetadata | undef
|
||||
if (hasKey(error, 'errorResponse')) {
|
||||
return parseErrorResponseWorkflowMetadata(error.errorResponse);
|
||||
}
|
||||
return undefined;
|
||||
|
||||
// This accounts for cases where the backend attaches the properties on plain errors
|
||||
// e.g. from custom nodes throwing literal `Error` or `ApplicationError` objects directly
|
||||
return parseErrorResponseWorkflowMetadata(error);
|
||||
}
|
||||
|
||||
@@ -2,12 +2,38 @@ import { parseErrorMetadata } from '@/MetadataUtils';
|
||||
|
||||
describe('MetadataUtils', () => {
|
||||
describe('parseMetadataFromError', () => {
|
||||
it('should return undefined if error does not have response', () => {
|
||||
const expectedMetadata = {
|
||||
subExecution: {
|
||||
executionId: '123',
|
||||
workflowId: '456',
|
||||
},
|
||||
subExecutionsCount: 1,
|
||||
};
|
||||
|
||||
it('should return undefined if error does not have response or both keys on the object', () => {
|
||||
const error = { message: 'An error occurred' };
|
||||
const result = parseErrorMetadata(error);
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should return undefined if errorResponse only has workflowId key', () => {
|
||||
const error = { errorResponse: { executionId: '123' } };
|
||||
const result = parseErrorMetadata(error);
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should return undefined if error only has executionId key', () => {
|
||||
const error = { executionId: '123' };
|
||||
const result = parseErrorMetadata(error);
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should support executionId and workflowId key directly on the error object', () => {
|
||||
const error = { executionId: '123', workflowId: '456' };
|
||||
const result = parseErrorMetadata(error);
|
||||
expect(result).toEqual(expectedMetadata);
|
||||
});
|
||||
|
||||
it('should return undefined if error response does not have subworkflow data', () => {
|
||||
const error = { errorResponse: { someKey: 'someValue' } };
|
||||
const result = parseErrorMetadata(error);
|
||||
@@ -16,13 +42,6 @@ describe('MetadataUtils', () => {
|
||||
|
||||
it('should return metadata if error response has subworkflow data', () => {
|
||||
const error = { errorResponse: { executionId: '123', workflowId: '456' } };
|
||||
const expectedMetadata = {
|
||||
subExecution: {
|
||||
executionId: '123',
|
||||
workflowId: '456',
|
||||
},
|
||||
subExecutionsCount: 1,
|
||||
};
|
||||
const result = parseErrorMetadata(error);
|
||||
expect(result).toEqual(expectedMetadata);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user