refactor(core): Reorganize error hierarchy in core and workflow packages (no-changelog) (#7820)

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`
This commit is contained in:
Iván Ovejero
2023-11-27 15:33:21 +01:00
committed by GitHub
parent aae45b043b
commit dff8456382
53 changed files with 758 additions and 694 deletions

View File

@@ -1,4 +1,5 @@
import { ExpressionError, ExpressionExtensionError } from '../ExpressionError';
import { ExpressionError } from '../errors/expression.error';
import { ExpressionExtensionError } from '../errors/expression-extension.error';
import type { ExtensionMap } from './Extensions';
import { compact as oCompact } from './ObjectExtensions';
import deepEqual from 'deep-equal';

View File

@@ -1,4 +1,4 @@
import { ExpressionExtensionError } from './../ExpressionError';
import { ExpressionExtensionError } from '../errors/expression-extension.error';
import { DateTime } from 'luxon';
import type {

View File

@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { DateTime } from 'luxon';
import { ExpressionExtensionError } from '../ExpressionError';
import { ExpressionExtensionError } from '../errors/expression-extension.error';
import { parse, visit, types, print } from 'recast';
import { getOption } from 'recast/lib/util';
import type { Config as EsprimaConfig } from 'esprima-next';

View File

@@ -1,4 +1,5 @@
import { ExpressionError, ExpressionExtensionError } from '../ExpressionError';
import { ExpressionError } from '../errors/expression.error';
import { ExpressionExtensionError } from '../errors/expression-extension.error';
import { average as aAverage } from './ArrayExtensions';
const min = Math.min;

View File

@@ -1,7 +1,7 @@
/**
* @jest-environment jsdom
*/
import { ExpressionExtensionError } from './../ExpressionError';
import { ExpressionExtensionError } from '../errors/expression-extension.error';
import type { ExtensionMap } from './Extensions';
function format(value: number, extraArgs: unknown[]): string {

View File

@@ -1,4 +1,4 @@
import { ExpressionExtensionError } from '../ExpressionError';
import { ExpressionExtensionError } from '../errors/expression-extension.error';
import type { ExtensionMap } from './Extensions';
function isEmpty(value: object): boolean {

View File

@@ -1,10 +1,10 @@
// import { createHash } from 'crypto';
import { titleCase } from 'title-case';
import * as ExpressionError from '../ExpressionError';
import type { ExtensionMap } from './Extensions';
import CryptoJS from 'crypto-js';
import { encode } from 'js-base64';
import { transliterate } from 'transliteration';
import { ExpressionExtensionError } from '../errors/expression-extension.error';
const hashFunctions: Record<string, typeof CryptoJS.MD5> = {
md5: CryptoJS.MD5,
@@ -122,7 +122,7 @@ function hash(value: string, extraArgs?: unknown): string {
}
const hashFunction = hashFunctions[algorithm.toLowerCase()];
if (!hashFunction) {
throw new ExpressionError.ExpressionExtensionError(
throw new ExpressionExtensionError(
`Unknown algorithm ${algorithm}. Available algorithms are: ${Object.keys(hashFunctions)
.map((s) => s.toUpperCase())
.join(', ')}, and Base64.`,
@@ -194,7 +194,7 @@ function toDate(value: string): Date {
const date = new Date(Date.parse(value));
if (date.toString() === 'Invalid Date') {
throw new ExpressionError.ExpressionExtensionError('cannot convert to date');
throw new ExpressionExtensionError('cannot convert to date');
}
// If time component is not specified, force 00:00h
if (!/:/.test(value)) {
@@ -224,7 +224,7 @@ function toInt(value: string, extraArgs: Array<number | undefined>) {
const int = parseInt(value.replace(CURRENCY_REGEXP, ''), radix);
if (isNaN(int)) {
throw new ExpressionError.ExpressionExtensionError('cannot convert to integer');
throw new ExpressionExtensionError('cannot convert to integer');
}
return int;
@@ -232,15 +232,13 @@ function toInt(value: string, extraArgs: Array<number | undefined>) {
function toFloat(value: string) {
if (value.includes(',')) {
throw new ExpressionError.ExpressionExtensionError(
'cannot convert to float, expected . as decimal separator',
);
throw new ExpressionExtensionError('cannot convert to float, expected . as decimal separator');
}
const float = parseFloat(value.replace(CURRENCY_REGEXP, ''));
if (isNaN(float)) {
throw new ExpressionError.ExpressionExtensionError('cannot convert to float');
throw new ExpressionExtensionError('cannot convert to float');
}
return float;