refactor(core): Switch plain errors in workflow to ApplicationError (no-changelog) (#7877)

Ensure all errors in `workflow` are `ApplicationError` or children of it
and contain no variables in the message, to continue normalizing all the
errors we report to Sentry

Follow-up to: https://github.com/n8n-io/n8n/pull/7873
This commit is contained in:
Iván Ovejero
2023-11-30 12:46:45 +01:00
committed by GitHub
parent ce2d388f05
commit 67702c2485
9 changed files with 110 additions and 61 deletions

View File

@@ -48,6 +48,7 @@ import { deepCopy } from './utils';
import { DateTime } from 'luxon';
import type { Workflow } from './Workflow';
import { ApplicationError } from './errors/application.error';
export const cronNodeOptions: INodePropertyCollection[] = [
{
@@ -416,7 +417,7 @@ export function getContext(
): IContextObject {
if (runExecutionData.executionData === undefined) {
// TODO: Should not happen leave it for test now
throw new Error('The "executionData" is not initialized!');
throw new ApplicationError('`executionData` is not initialized');
}
let key: string;
@@ -424,11 +425,16 @@ export function getContext(
key = 'flow';
} else if (type === 'node') {
if (node === undefined) {
throw new Error('The request data of context type "node" the node parameter has to be set!');
// @TODO: What does this mean?
throw new ApplicationError(
'The request data of context type "node" the node parameter has to be set!',
);
}
key = `node:${node.name}`;
} else {
throw new Error(`The context type "${type}" is not know. Only "flow" and node" are supported!`);
throw new ApplicationError('Unknown context type. Only `flow` and `node` are supported.', {
extra: { contextType: type },
});
}
if (runExecutionData.executionData.contextData[key] === undefined) {
@@ -530,7 +536,7 @@ export function getParameterResolveOrder(
}
if (iterations > lastIndexReduction + nodePropertiesArray.length) {
throw new Error(
throw new ApplicationError(
'Could not resolve parameter dependencies. Max iterations reached! Hint: If `displayOptions` are specified in any child parameter of a parent `collection` or `fixedCollection`, remove the `displayOptions` from the child parameter.',
);
}
@@ -773,9 +779,9 @@ export function getNodeParameters(
) as INodePropertyCollection;
if (nodePropertyOptions === undefined) {
throw new Error(
`Could not find property option "${itemName}" for "${nodeProperties.name}"`,
);
throw new ApplicationError('Could not find property option', {
extra: { propertyOption: itemName, property: nodeProperties.name },
});
}
tempNodePropertiesArray = nodePropertyOptions.values!;
@@ -1054,7 +1060,9 @@ export function getNodeInputs(
{},
) || []) as ConnectionTypes[];
} catch (e) {
throw new Error(`Could not calculate inputs dynamically for node "${node.name}"`);
throw new ApplicationError('Could not calculate inputs dynamically for node', {
extra: { nodeName: node.name },
});
}
}
@@ -1077,7 +1085,9 @@ export function getNodeOutputs(
{},
) || []) as ConnectionTypes[];
} catch (e) {
throw new Error(`Could not calculate outputs dynamically for node "${node.name}"`);
throw new ApplicationError('Could not calculate outputs dynamically for node', {
extra: { nodeName: node.name },
});
}
}
@@ -1258,7 +1268,7 @@ export const tryToParseNumber = (value: unknown): number => {
const isValidNumber = !isNaN(Number(value));
if (!isValidNumber) {
throw new Error(`Could not parse '${String(value)}' to number.`);
throw new ApplicationError('Failed to parse value to number', { extra: { value } });
}
return Number(value);
};
@@ -1282,7 +1292,9 @@ export const tryToParseBoolean = (value: unknown): value is boolean => {
}
}
throw new Error(`Could not parse '${String(value)}' to boolean.`);
throw new ApplicationError('Failed to parse value as boolean', {
extra: { value },
});
};
export const tryToParseDateTime = (value: unknown): DateTime => {
@@ -1306,7 +1318,7 @@ export const tryToParseDateTime = (value: unknown): DateTime => {
return sqlDate;
}
throw new Error(`The value "${dateString}" is not a valid date.`);
throw new ApplicationError('Value is not a valid date', { extra: { dateString } });
};
export const tryToParseTime = (value: unknown): string => {
@@ -1314,7 +1326,7 @@ export const tryToParseTime = (value: unknown): string => {
String(value),
);
if (!isTimeInput) {
throw new Error(`The value "${String(value)}" is not a valid time.`);
throw new ApplicationError('Value is not a valid time', { extra: { value } });
}
return String(value);
};
@@ -1333,11 +1345,11 @@ export const tryToParseArray = (value: unknown): unknown[] => {
}
if (!Array.isArray(parsed)) {
throw new Error(`The value "${String(value)}" is not a valid array.`);
throw new ApplicationError('Value is not a valid array', { extra: { value } });
}
return parsed;
} catch (e) {
throw new Error(`The value "${String(value)}" is not a valid array.`);
throw new ApplicationError('Value is not a valid array', { extra: { value } });
}
};
@@ -1348,11 +1360,11 @@ export const tryToParseObject = (value: unknown): object => {
try {
const o = JSON.parse(String(value));
if (typeof o !== 'object' || Array.isArray(o)) {
throw new Error(`The value "${String(value)}" is not a valid object.`);
throw new ApplicationError('Value is not a valid object', { extra: { value } });
}
return o;
} catch (e) {
throw new Error(`The value "${String(value)}" is not a valid object.`);
throw new ApplicationError('Value is not a valid object', { extra: { value } });
}
};