mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(core): Move error obfuscation to FE (no-changelog) (#10237)
This commit is contained in:
parent
06419d9483
commit
c0bdf3b719
|
@ -44,7 +44,7 @@ import {
|
||||||
ApplicationError,
|
ApplicationError,
|
||||||
NodeExecutionOutput,
|
NodeExecutionOutput,
|
||||||
sleep,
|
sleep,
|
||||||
OBFUSCATED_ERROR_MESSAGE,
|
ErrorReporterProxy,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import * as NodeExecuteFunctions from './NodeExecuteFunctions';
|
import * as NodeExecuteFunctions from './NodeExecuteFunctions';
|
||||||
|
@ -1318,12 +1318,30 @@ export class WorkflowExecute {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.runExecutionData.resultData.lastNodeExecuted = executionData.node.name;
|
this.runExecutionData.resultData.lastNodeExecuted = executionData.node.name;
|
||||||
|
|
||||||
const message =
|
let toReport: Error | undefined;
|
||||||
error instanceof ApplicationError ? error.message : OBFUSCATED_ERROR_MESSAGE;
|
if (error instanceof ApplicationError) {
|
||||||
|
// Report any unhandled errors that were wrapped in by one of our error classes
|
||||||
|
if (error.cause instanceof Error) toReport = error.cause;
|
||||||
|
} else {
|
||||||
|
// Report any unhandled and non-wrapped errors to Sentry
|
||||||
|
toReport = error;
|
||||||
|
// Set obfuscate to true so that the error would be obfuscated in th UI
|
||||||
|
error.obfuscate = true;
|
||||||
|
}
|
||||||
|
if (toReport) {
|
||||||
|
ErrorReporterProxy.error(toReport, {
|
||||||
|
extra: {
|
||||||
|
nodeName: executionNode.name,
|
||||||
|
nodeType: executionNode.type,
|
||||||
|
nodeVersion: executionNode.typeVersion,
|
||||||
|
workflowId: workflow.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const e = error as unknown as ExecutionBaseError;
|
const e = error as unknown as ExecutionBaseError;
|
||||||
|
|
||||||
executionError = { ...e, message, stack: e.stack };
|
executionError = { ...e, message: e.message, stack: e.stack };
|
||||||
|
|
||||||
Logger.debug(`Running node "${executionNode.name}" finished with error`, {
|
Logger.debug(`Running node "${executionNode.name}" finished with error`, {
|
||||||
node: executionNode.name,
|
node: executionNode.name,
|
||||||
|
|
|
@ -179,6 +179,10 @@ function addItemIndexSuffix(message: string): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getErrorMessage(): string {
|
function getErrorMessage(): string {
|
||||||
|
if ('obfuscate' in props.error && props.error.obfuscate === true) {
|
||||||
|
return i18n.baseText('nodeErrorView.showMessage.obfuscate');
|
||||||
|
}
|
||||||
|
|
||||||
let message = '';
|
let message = '';
|
||||||
|
|
||||||
const isSubNodeError =
|
const isSubNodeError =
|
||||||
|
|
|
@ -1125,6 +1125,7 @@
|
||||||
"nodeErrorView.itemIndex": "Item Index",
|
"nodeErrorView.itemIndex": "Item Index",
|
||||||
"nodeErrorView.runIndex": "Run Index",
|
"nodeErrorView.runIndex": "Run Index",
|
||||||
"nodeErrorView.showMessage.title": "Copied to clipboard",
|
"nodeErrorView.showMessage.title": "Copied to clipboard",
|
||||||
|
"nodeErrorView.showMessage.obfuscate": "Internal error",
|
||||||
"nodeErrorView.stack": "Stack",
|
"nodeErrorView.stack": "Stack",
|
||||||
"nodeErrorView.theErrorCauseIsTooLargeToBeDisplayed": "The error cause is too large to be displayed",
|
"nodeErrorView.theErrorCauseIsTooLargeToBeDisplayed": "The error cause is too large to be displayed",
|
||||||
"nodeErrorView.time": "Time",
|
"nodeErrorView.time": "Time",
|
||||||
|
|
|
@ -2,7 +2,6 @@ import type { INode, JsonObject } from '@/Interfaces';
|
||||||
import type { NodeOperationErrorOptions } from './node-api.error';
|
import type { NodeOperationErrorOptions } from './node-api.error';
|
||||||
import { NodeError } from './abstract/node.error';
|
import { NodeError } from './abstract/node.error';
|
||||||
import { ApplicationError } from './application.error';
|
import { ApplicationError } from './application.error';
|
||||||
import { OBFUSCATED_ERROR_MESSAGE } from '../Constants';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for instantiating an operational error, e.g. an invalid credentials error.
|
* Class for instantiating an operational error, e.g. an invalid credentials error.
|
||||||
|
@ -10,6 +9,8 @@ import { OBFUSCATED_ERROR_MESSAGE } from '../Constants';
|
||||||
export class NodeOperationError extends NodeError {
|
export class NodeOperationError extends NodeError {
|
||||||
type: string | undefined;
|
type: string | undefined;
|
||||||
|
|
||||||
|
obfuscate: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
node: INode,
|
node: INode,
|
||||||
error: Error | string | JsonObject,
|
error: Error | string | JsonObject,
|
||||||
|
@ -22,7 +23,7 @@ export class NodeOperationError extends NodeError {
|
||||||
let obfuscateErrorMessage = false;
|
let obfuscateErrorMessage = false;
|
||||||
|
|
||||||
if (typeof error === 'string') {
|
if (typeof error === 'string') {
|
||||||
error = new Error(error);
|
error = new ApplicationError(error);
|
||||||
} else if (!(error instanceof ApplicationError)) {
|
} else if (!(error instanceof ApplicationError)) {
|
||||||
// this error was no processed by n8n, obfuscate error message
|
// this error was no processed by n8n, obfuscate error message
|
||||||
obfuscateErrorMessage = true;
|
obfuscateErrorMessage = true;
|
||||||
|
@ -37,7 +38,7 @@ export class NodeOperationError extends NodeError {
|
||||||
if (obfuscateErrorMessage && !options.description) {
|
if (obfuscateErrorMessage && !options.description) {
|
||||||
const originalMessage = typeof error === 'string' ? error : (error.message as string);
|
const originalMessage = typeof error === 'string' ? error : (error.message as string);
|
||||||
this.addToMessages(originalMessage);
|
this.addToMessages(originalMessage);
|
||||||
this.message = OBFUSCATED_ERROR_MESSAGE;
|
this.obfuscate = true;
|
||||||
}
|
}
|
||||||
if (options.message) this.message = options.message;
|
if (options.message) this.message = options.message;
|
||||||
if (options.level) this.level = options.level;
|
if (options.level) this.level = options.level;
|
||||||
|
|
|
@ -3,7 +3,6 @@ import type { INode } from '@/Interfaces';
|
||||||
import { NodeApiError } from '@/errors/node-api.error';
|
import { NodeApiError } from '@/errors/node-api.error';
|
||||||
import { NodeOperationError } from '@/errors/node-operation.error';
|
import { NodeOperationError } from '@/errors/node-operation.error';
|
||||||
import { ApplicationError } from '@/errors/application.error';
|
import { ApplicationError } from '@/errors/application.error';
|
||||||
import { OBFUSCATED_ERROR_MESSAGE } from '@/Constants';
|
|
||||||
|
|
||||||
describe('NodeError', () => {
|
describe('NodeError', () => {
|
||||||
const node = mock<INode>();
|
const node = mock<INode>();
|
||||||
|
@ -22,7 +21,8 @@ describe('NodeError', () => {
|
||||||
const error = new Error('Original error message');
|
const error = new Error('Original error message');
|
||||||
const nodeOpError = new NodeOperationError(node, error);
|
const nodeOpError = new NodeOperationError(node, error);
|
||||||
|
|
||||||
expect(nodeOpError.message).toBe(OBFUSCATED_ERROR_MESSAGE);
|
expect(nodeOpError.obfuscate).toBe(true);
|
||||||
|
expect(nodeOpError.message).toBe('Original error message');
|
||||||
expect(nodeOpError.messages).toContain('Original error message');
|
expect(nodeOpError.messages).toContain('Original error message');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ describe('NodeError', () => {
|
||||||
const appError = new ApplicationError('Processed error message');
|
const appError = new ApplicationError('Processed error message');
|
||||||
const nodeOpError = new NodeOperationError(node, appError);
|
const nodeOpError = new NodeOperationError(node, appError);
|
||||||
|
|
||||||
|
expect(nodeOpError.obfuscate).toBe(false);
|
||||||
expect(nodeOpError.message).toBe('Processed error message');
|
expect(nodeOpError.message).toBe('Processed error message');
|
||||||
expect(nodeOpError.messages).not.toContain('Processed error message');
|
expect(nodeOpError.messages).not.toContain('Processed error message');
|
||||||
});
|
});
|
||||||
|
@ -38,6 +39,7 @@ describe('NodeError', () => {
|
||||||
const errorMessage = 'String error message';
|
const errorMessage = 'String error message';
|
||||||
const nodeOpError = new NodeOperationError(node, errorMessage);
|
const nodeOpError = new NodeOperationError(node, errorMessage);
|
||||||
|
|
||||||
|
expect(nodeOpError.obfuscate).toBe(false);
|
||||||
expect(nodeOpError.message).toBe(errorMessage);
|
expect(nodeOpError.message).toBe(errorMessage);
|
||||||
expect(nodeOpError.messages).toHaveLength(0);
|
expect(nodeOpError.messages).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
@ -47,6 +49,7 @@ describe('NodeError', () => {
|
||||||
const options = { description: 'Error description' };
|
const options = { description: 'Error description' };
|
||||||
const nodeOpError = new NodeOperationError(node, error, options);
|
const nodeOpError = new NodeOperationError(node, error, options);
|
||||||
|
|
||||||
|
expect(nodeOpError.obfuscate).toBe(false);
|
||||||
expect(nodeOpError.message).toBe('Initial error message');
|
expect(nodeOpError.message).toBe('Initial error message');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -55,6 +58,7 @@ describe('NodeError', () => {
|
||||||
const options = { message: 'Overridden message', description: 'Error description' };
|
const options = { message: 'Overridden message', description: 'Error description' };
|
||||||
const nodeOpError = new NodeOperationError(node, error, options);
|
const nodeOpError = new NodeOperationError(node, error, options);
|
||||||
|
|
||||||
|
expect(nodeOpError.obfuscate).toBe(false);
|
||||||
expect(nodeOpError.message).toBe('Overridden message');
|
expect(nodeOpError.message).toBe('Overridden message');
|
||||||
expect(nodeOpError.description).toBe('Error description');
|
expect(nodeOpError.description).toBe('Error description');
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue