mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-20 03:12:15 +00:00
Ensure all errors in `core` and `workflow` inherit from `ApplicationError` so that we start normalizing all the errors we report to Sentry Follow-up to: https://github.com/n8n-io/n8n/pull/7757#discussion_r1404338844 ### `core` package `ApplicationError` - `FileSystemError` (abstract) - `FileNotFoundError` - `DisallowedFilepathError` - `BinaryDataError` (abstract) - `InvalidModeError` - `InvalidManagerError` - `InvalidExecutionMetadataError` ### `workflow` package `ApplicationError` - `ExecutionBaseError` (abstract) - `WorkflowActivationError` - `WorkflowDeactivationError` - `WebhookTakenError` - `WorkflowOperationError` - `SubworkflowOperationError` - `CliWorkflowOperationError` - `ExpressionError` - `ExpressionExtensionError` - `NodeError` (abstract) - `NodeOperationError` - `NodeApiError` - `NodeSSLError` Up next: - Reorganize errors in `cli` - Flatten the hierarchy in `workflow` (do we really need `ExecutionBaseError`?) - Remove `ExecutionError` type - Stop throwing plain `Error`s - Replace `severity` with `level` - Add node and credential types as `tags` - Add workflow IDs and execution IDs as `extras`
86 lines
2.0 KiB
TypeScript
86 lines
2.0 KiB
TypeScript
import { ExpressionError } from '../errors/expression.error';
|
|
import { ExpressionExtensionError } from '../errors/expression-extension.error';
|
|
import { average as aAverage } from './ArrayExtensions';
|
|
|
|
const min = Math.min;
|
|
const max = Math.max;
|
|
|
|
const numberList = (start: number, end: number): number[] => {
|
|
const size = Math.abs(start - end) + 1;
|
|
const arr = new Array<number>(size);
|
|
|
|
let curr = start;
|
|
for (let i = 0; i < size; i++) {
|
|
if (start < end) {
|
|
arr[i] = curr++;
|
|
} else {
|
|
arr[i] = curr--;
|
|
}
|
|
}
|
|
|
|
return arr;
|
|
};
|
|
|
|
const zip = (keys: unknown[], values: unknown[]): unknown => {
|
|
if (keys.length !== values.length) {
|
|
throw new ExpressionExtensionError('keys and values not of equal length');
|
|
}
|
|
return keys.reduce((p, c, i) => {
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
(p as any)[c as any] = values[i];
|
|
return p;
|
|
}, {});
|
|
};
|
|
|
|
const average = (...args: number[]) => {
|
|
return aAverage(args);
|
|
};
|
|
|
|
const not = (value: unknown): boolean => {
|
|
return !value;
|
|
};
|
|
|
|
function ifEmpty<T, V>(value: V, defaultValue: T) {
|
|
if (arguments.length !== 2) {
|
|
throw new ExpressionError('expected two arguments (value, defaultValue) for this function');
|
|
}
|
|
if (value === undefined || value === null || value === '') {
|
|
return defaultValue;
|
|
}
|
|
if (typeof value === 'object') {
|
|
if (Array.isArray(value) && !value.length) {
|
|
return defaultValue;
|
|
}
|
|
if (!Object.keys(value).length) {
|
|
return defaultValue;
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
|
|
ifEmpty.doc = {
|
|
name: 'ifEmpty',
|
|
description:
|
|
'Returns the default value if the value is empty. Empty values are undefined, null, empty strings, arrays without elements and objects without keys.',
|
|
returnType: 'any',
|
|
args: [
|
|
{ name: 'value', type: 'any' },
|
|
{ name: 'defaultValue', type: 'any' },
|
|
],
|
|
docURL: 'https://docs.n8n.io/code/builtin/convenience',
|
|
};
|
|
|
|
export const extendedFunctions = {
|
|
min,
|
|
max,
|
|
not,
|
|
average,
|
|
numberList,
|
|
zip,
|
|
$min: min,
|
|
$max: max,
|
|
$average: average,
|
|
$not: not,
|
|
$ifEmpty: ifEmpty,
|
|
};
|