mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
refactor(core): Switch plain errors in core to ApplicationError (no-changelog) (#7873)
Ensure all errors in `core` 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/7857
This commit is contained in:
@@ -112,6 +112,7 @@ import {
|
||||
validateFieldType,
|
||||
ExecutionBaseError,
|
||||
jsonParse,
|
||||
ApplicationError,
|
||||
} from 'n8n-workflow';
|
||||
import type { Token } from 'oauth-1.0a';
|
||||
import clientOAuth1 from 'oauth-1.0a';
|
||||
@@ -1198,7 +1199,7 @@ export async function requestOAuth2(
|
||||
credentials.grantType === OAuth2GrantType.authorizationCode &&
|
||||
credentials.oauthTokenData === undefined
|
||||
) {
|
||||
throw new Error('OAuth credentials not connected!');
|
||||
throw new ApplicationError('OAuth credentials not connected');
|
||||
}
|
||||
|
||||
const oAuthClient = new ClientOAuth2({
|
||||
@@ -1218,9 +1219,10 @@ export async function requestOAuth2(
|
||||
const { data } = await getClientCredentialsToken(oAuthClient, credentials);
|
||||
// Find the credentials
|
||||
if (!node.credentials?.[credentialsType]) {
|
||||
throw new Error(
|
||||
`The node "${node.name}" does not have credentials of type "${credentialsType}"!`,
|
||||
);
|
||||
throw new ApplicationError('Node does not have credential type', {
|
||||
extra: { nodeName: node.name },
|
||||
tags: { credentialType: credentialsType },
|
||||
});
|
||||
}
|
||||
|
||||
const nodeCredentials = node.credentials[credentialsType];
|
||||
@@ -1302,9 +1304,9 @@ export async function requestOAuth2(
|
||||
credentials.oauthTokenData = newToken.data;
|
||||
// Find the credentials
|
||||
if (!node.credentials?.[credentialsType]) {
|
||||
throw new Error(
|
||||
`The node "${node.name}" does not have credentials of type "${credentialsType}"!`,
|
||||
);
|
||||
throw new ApplicationError('Node does not have credential type', {
|
||||
extra: { nodeName: node.name, credentialType: credentialsType },
|
||||
});
|
||||
}
|
||||
const nodeCredentials = node.credentials[credentialsType];
|
||||
await additionalData.credentialsHelper.updateCredentials(
|
||||
@@ -1379,9 +1381,10 @@ export async function requestOAuth2(
|
||||
|
||||
// Find the credentials
|
||||
if (!node.credentials?.[credentialsType]) {
|
||||
throw new Error(
|
||||
`The node "${node.name}" does not have credentials of type "${credentialsType}"!`,
|
||||
);
|
||||
throw new ApplicationError('Node does not have credential type', {
|
||||
tags: { credentialType: credentialsType },
|
||||
extra: { nodeName: node.name },
|
||||
});
|
||||
}
|
||||
const nodeCredentials = node.credentials[credentialsType];
|
||||
|
||||
@@ -1426,11 +1429,11 @@ export async function requestOAuth1(
|
||||
const credentials = await this.getCredentials(credentialsType);
|
||||
|
||||
if (credentials === undefined) {
|
||||
throw new Error('No credentials were returned!');
|
||||
throw new ApplicationError('No credentials were returned!');
|
||||
}
|
||||
|
||||
if (credentials.oauthTokenData === undefined) {
|
||||
throw new Error('OAuth credentials not connected!');
|
||||
throw new ApplicationError('OAuth credentials not connected!');
|
||||
}
|
||||
|
||||
const oauth = new clientOAuth1({
|
||||
@@ -1651,7 +1654,7 @@ export function normalizeItems(
|
||||
return executionData;
|
||||
|
||||
if (executionData.some((item) => typeof item === 'object' && 'json' in item)) {
|
||||
throw new Error('Inconsistent item format');
|
||||
throw new ApplicationError('Inconsistent item format');
|
||||
}
|
||||
|
||||
if (executionData.every((item) => typeof item === 'object' && 'binary' in item)) {
|
||||
@@ -1671,7 +1674,7 @@ export function normalizeItems(
|
||||
}
|
||||
|
||||
if (executionData.some((item) => typeof item === 'object' && 'binary' in item)) {
|
||||
throw new Error('Inconsistent item format');
|
||||
throw new ApplicationError('Inconsistent item format');
|
||||
}
|
||||
|
||||
return executionData.map((item) => {
|
||||
@@ -2229,13 +2232,15 @@ export function getNodeParameter(
|
||||
): NodeParameterValueType | object {
|
||||
const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
|
||||
if (nodeType === undefined) {
|
||||
throw new Error(`Node type "${node.type}" is not known so can not return parameter value!`);
|
||||
throw new ApplicationError('Node type is unknown so cannot return parameter value', {
|
||||
tags: { nodeType: node.type },
|
||||
});
|
||||
}
|
||||
|
||||
const value = get(node.parameters, parameterName, fallbackValue);
|
||||
|
||||
if (value === undefined) {
|
||||
throw new Error(`Could not get parameter "${parameterName}"!`);
|
||||
throw new ApplicationError('Could not get parameter', { extra: { parameterName } });
|
||||
}
|
||||
|
||||
if (options?.rawExpressions) {
|
||||
@@ -2393,7 +2398,9 @@ const addExecutionDataFunctions = async (
|
||||
currentNodeRunIndex: number,
|
||||
): Promise<void> => {
|
||||
if (connectionType === 'main') {
|
||||
throw new Error(`Setting the ${type} is not supported for the main connection!`);
|
||||
throw new ApplicationError('Setting type is not supported for main connection', {
|
||||
extra: { type },
|
||||
});
|
||||
}
|
||||
|
||||
let taskData: ITaskData | undefined;
|
||||
@@ -2946,7 +2953,7 @@ const getBinaryHelperFunctions = (
|
||||
setBinaryDataBuffer: async (data, binaryData) =>
|
||||
setBinaryDataBuffer(data, binaryData, workflowId, executionId!),
|
||||
copyBinaryFile: async () => {
|
||||
throw new Error('copyBinaryFile has been removed. Please upgrade this node');
|
||||
throw new ApplicationError('`copyBinaryFile` has been removed. Please upgrade this node.');
|
||||
},
|
||||
});
|
||||
|
||||
@@ -2983,10 +2990,12 @@ export function getExecutePollFunctions(
|
||||
return {
|
||||
...getCommonWorkflowFunctions(workflow, node, additionalData),
|
||||
__emit: (data: INodeExecutionData[][]): void => {
|
||||
throw new Error('Overwrite NodeExecuteFunctions.getExecutePollFunctions.__emit function!');
|
||||
throw new ApplicationError(
|
||||
'Overwrite NodeExecuteFunctions.getExecutePollFunctions.__emit function!',
|
||||
);
|
||||
},
|
||||
__emitError(error: Error) {
|
||||
throw new Error(
|
||||
throw new ApplicationError(
|
||||
'Overwrite NodeExecuteFunctions.getExecutePollFunctions.__emitError function!',
|
||||
);
|
||||
},
|
||||
@@ -3043,10 +3052,14 @@ export function getExecuteTriggerFunctions(
|
||||
return {
|
||||
...getCommonWorkflowFunctions(workflow, node, additionalData),
|
||||
emit: (data: INodeExecutionData[][]): void => {
|
||||
throw new Error('Overwrite NodeExecuteFunctions.getExecuteTriggerFunctions.emit function!');
|
||||
throw new ApplicationError(
|
||||
'Overwrite NodeExecuteFunctions.getExecuteTriggerFunctions.emit function!',
|
||||
);
|
||||
},
|
||||
emitError: (error: Error): void => {
|
||||
throw new Error('Overwrite NodeExecuteFunctions.getExecuteTriggerFunctions.emit function!');
|
||||
throw new ApplicationError(
|
||||
'Overwrite NodeExecuteFunctions.getExecuteTriggerFunctions.emit function!',
|
||||
);
|
||||
},
|
||||
getMode: () => mode,
|
||||
getActivationMode: () => activation,
|
||||
@@ -3174,7 +3187,9 @@ export function getExecuteFunctions(
|
||||
});
|
||||
|
||||
if (inputConfiguration === undefined) {
|
||||
throw new Error(`The node "${node.name}" does not have an input of type "${inputName}"`);
|
||||
throw new ApplicationError('Node does not have input of type', {
|
||||
extra: { nodeName: node.name, inputName },
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof inputConfiguration === 'string') {
|
||||
@@ -3200,9 +3215,9 @@ export function getExecuteFunctions(
|
||||
);
|
||||
|
||||
if (!nodeType.supplyData) {
|
||||
throw new Error(
|
||||
`The node "${connectedNode.name}" does not have a "supplyData" method defined!`,
|
||||
);
|
||||
throw new ApplicationError('Node does not have a `supplyData` method defined', {
|
||||
extra: { nodeName: connectedNode.name },
|
||||
});
|
||||
}
|
||||
|
||||
const context = Object.assign({}, this);
|
||||
@@ -3350,12 +3365,15 @@ export function getExecuteFunctions(
|
||||
|
||||
// TODO: Check if nodeType has input with that index defined
|
||||
if (inputData[inputName].length < inputIndex) {
|
||||
throw new Error(`Could not get input index "${inputIndex}" of input "${inputName}"!`);
|
||||
throw new ApplicationError('Could not get input with given index', {
|
||||
extra: { inputIndex, inputName },
|
||||
});
|
||||
}
|
||||
|
||||
if (inputData[inputName][inputIndex] === null) {
|
||||
// return [];
|
||||
throw new Error(`Value "${inputIndex}" of input "${inputName}" did not get set!`);
|
||||
throw new ApplicationError('Value of input was not set', {
|
||||
extra: { inputIndex, inputName },
|
||||
});
|
||||
}
|
||||
|
||||
return inputData[inputName][inputIndex] as INodeExecutionData[];
|
||||
@@ -3363,7 +3381,7 @@ export function getExecuteFunctions(
|
||||
getInputSourceData: (inputIndex = 0, inputName = 'main') => {
|
||||
if (executeData?.source === null) {
|
||||
// Should never happen as n8n sets it automatically
|
||||
throw new Error('Source data is missing!');
|
||||
throw new ApplicationError('Source data is missing');
|
||||
}
|
||||
return executeData.source[inputName][inputIndex];
|
||||
},
|
||||
@@ -3573,21 +3591,23 @@ export function getExecuteSingleFunctions(
|
||||
|
||||
// TODO: Check if nodeType has input with that index defined
|
||||
if (inputData[inputName].length < inputIndex) {
|
||||
throw new Error(`Could not get input index "${inputIndex}" of input "${inputName}"!`);
|
||||
throw new ApplicationError('Could not get input index', {
|
||||
extra: { inputIndex, inputName },
|
||||
});
|
||||
}
|
||||
|
||||
const allItems = inputData[inputName][inputIndex];
|
||||
|
||||
if (allItems === null) {
|
||||
// return [];
|
||||
throw new Error(`Value "${inputIndex}" of input "${inputName}" did not get set!`);
|
||||
throw new ApplicationError('Input index was not set', {
|
||||
extra: { inputIndex, inputName },
|
||||
});
|
||||
}
|
||||
|
||||
if (allItems[itemIndex] === null) {
|
||||
// return [];
|
||||
throw new Error(
|
||||
`Value "${inputIndex}" of input "${inputName}" with itemIndex "${itemIndex}" did not get set!`,
|
||||
);
|
||||
throw new ApplicationError('Value of input with given index was not set', {
|
||||
extra: { inputIndex, inputName, itemIndex },
|
||||
});
|
||||
}
|
||||
|
||||
return allItems[itemIndex];
|
||||
@@ -3595,7 +3615,7 @@ export function getExecuteSingleFunctions(
|
||||
getInputSourceData: (inputIndex = 0, inputName = 'main') => {
|
||||
if (executeData?.source === null) {
|
||||
// Should never happen as n8n sets it automatically
|
||||
throw new Error('Source data is missing!');
|
||||
throw new ApplicationError('Source data is missing');
|
||||
}
|
||||
return executeData.source[inputName][inputIndex] as ISourceData;
|
||||
},
|
||||
@@ -3691,9 +3711,9 @@ export function getLoadOptionsFunctions(
|
||||
if (options?.extractValue) {
|
||||
const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
|
||||
if (nodeType === undefined) {
|
||||
throw new Error(
|
||||
`Node type "${node.type}" is not known so can not return parameter value!`,
|
||||
);
|
||||
throw new ApplicationError('Node type is not known so cannot return parameter value', {
|
||||
tags: { nodeType: node.type },
|
||||
});
|
||||
}
|
||||
returnData = extractValue(
|
||||
returnData,
|
||||
@@ -3793,7 +3813,7 @@ export function getExecuteHookFunctions(
|
||||
},
|
||||
getWebhookName(): string {
|
||||
if (webhookData === undefined) {
|
||||
throw new Error('Is only supported in webhook functions!');
|
||||
throw new ApplicationError('Only supported in webhook functions');
|
||||
}
|
||||
return webhookData.webhookDescription.name;
|
||||
},
|
||||
@@ -3818,14 +3838,14 @@ export function getExecuteWebhookFunctions(
|
||||
...getCommonWorkflowFunctions(workflow, node, additionalData),
|
||||
getBodyData(): IDataObject {
|
||||
if (additionalData.httpRequest === undefined) {
|
||||
throw new Error('Request is missing!');
|
||||
throw new ApplicationError('Request is missing');
|
||||
}
|
||||
return additionalData.httpRequest.body;
|
||||
},
|
||||
getCredentials: async (type) => getCredentials(workflow, node, type, additionalData, mode),
|
||||
getHeaderData(): IncomingHttpHeaders {
|
||||
if (additionalData.httpRequest === undefined) {
|
||||
throw new Error('Request is missing!');
|
||||
throw new ApplicationError('Request is missing');
|
||||
}
|
||||
return additionalData.httpRequest.headers;
|
||||
},
|
||||
@@ -3857,25 +3877,25 @@ export function getExecuteWebhookFunctions(
|
||||
},
|
||||
getParamsData(): object {
|
||||
if (additionalData.httpRequest === undefined) {
|
||||
throw new Error('Request is missing!');
|
||||
throw new ApplicationError('Request is missing');
|
||||
}
|
||||
return additionalData.httpRequest.params;
|
||||
},
|
||||
getQueryData(): object {
|
||||
if (additionalData.httpRequest === undefined) {
|
||||
throw new Error('Request is missing!');
|
||||
throw new ApplicationError('Request is missing');
|
||||
}
|
||||
return additionalData.httpRequest.query;
|
||||
},
|
||||
getRequestObject(): Request {
|
||||
if (additionalData.httpRequest === undefined) {
|
||||
throw new Error('Request is missing!');
|
||||
throw new ApplicationError('Request is missing');
|
||||
}
|
||||
return additionalData.httpRequest;
|
||||
},
|
||||
getResponseObject(): Response {
|
||||
if (additionalData.httpResponse === undefined) {
|
||||
throw new Error('Response is missing!');
|
||||
throw new ApplicationError('Response is missing');
|
||||
}
|
||||
return additionalData.httpResponse;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user