refactor: Remove usless catch blocks, and add a linting rule to prevent them (no-changelog) (#12730)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2025-01-20 18:20:04 +01:00 committed by GitHub
parent 4ee4552b0e
commit 202da76380
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 220 additions and 242 deletions

View file

@ -392,13 +392,9 @@ export const createVectorStoreNode = (args: VectorStoreNodeConstructorArgs) =>
); );
resultData.push(...serializedDocuments); resultData.push(...serializedDocuments);
try { await args.populateVectorStore(this, embeddings, processedDocuments, itemIndex);
await args.populateVectorStore(this, embeddings, processedDocuments, itemIndex);
logAiEvent(this, 'ai-vector-store-populated'); logAiEvent(this, 'ai-vector-store-populated');
} catch (error) {
throw error;
}
} }
return [resultData]; return [resultData];
@ -443,16 +439,12 @@ export const createVectorStoreNode = (args: VectorStoreNodeConstructorArgs) =>
resultData.push(...serializedDocuments); resultData.push(...serializedDocuments);
try { // Use ids option to upsert instead of insert
// Use ids option to upsert instead of insert await vectorStore.addDocuments(processedDocuments, {
await vectorStore.addDocuments(processedDocuments, { ids: [documentId],
ids: [documentId], });
});
logAiEvent(this, 'ai-vector-store-updated'); logAiEvent(this, 'ai-vector-store-updated');
} catch (error) {
throw error;
}
} }
return [resultData]; return [resultData];

View file

@ -369,6 +369,8 @@ const config = (module.exports = {
'n8n-local-rules/no-unused-param-in-catch-clause': 'error', 'n8n-local-rules/no-unused-param-in-catch-clause': 'error',
'n8n-local-rules/no-useless-catch-throw': 'error',
'n8n-local-rules/no-plain-errors': 'error', 'n8n-local-rules/no-plain-errors': 'error',
// ****************************************************************** // ******************************************************************

View file

@ -172,6 +172,49 @@ module.exports = {
}, },
}, },
'no-useless-catch-throw': {
meta: {
type: 'problem',
docs: {
description: 'Disallow `try-catch` blocks where the `catch` only contains a `throw error`.',
recommended: 'error',
},
messages: {
noUselessCatchThrow: 'Remove useless `catch` block.',
},
fixable: 'code',
},
create(context) {
return {
CatchClause(node) {
if (
node.body.body.length === 1 &&
node.body.body[0].type === 'ThrowStatement' &&
node.body.body[0].argument.type === 'Identifier' &&
node.body.body[0].argument.name === node.param.name
) {
context.report({
node,
messageId: 'noUselessCatchThrow',
fix(fixer) {
const tryStatement = node.parent;
const tryBlock = tryStatement.block;
const sourceCode = context.getSourceCode();
const tryBlockText = sourceCode.getText(tryBlock);
const tryBlockTextWithoutBraces = tryBlockText.slice(1, -1).trim();
const indentedTryBlockText = tryBlockTextWithoutBraces
.split('\n')
.map((line) => line.replace(/\t/, ''))
.join('\n');
return fixer.replaceText(tryStatement, indentedTryBlockText);
},
});
}
},
};
},
},
'no-skipped-tests': { 'no-skipped-tests': {
meta: { meta: {
type: 'problem', type: 'problem',

View file

@ -51,3 +51,33 @@ ruleTester.run('no-json-parse-json-stringify', rules['no-json-parse-json-stringi
}, },
], ],
}); });
ruleTester.run('no-useless-catch-throw', rules['no-useless-catch-throw'], {
valid: [
{
code: 'try { foo(); } catch (e) { console.error(e); }',
},
{
code: 'try { foo(); } catch (e) { throw new Error("Custom error"); }',
},
],
invalid: [
{
code: `
try {
// Some comment
if (foo) {
bar();
}
} catch (e) {
throw e;
}`,
errors: [{ messageId: 'noUselessCatchThrow' }],
output: `
// Some comment
if (foo) {
bar();
}`,
},
],
});

View file

@ -161,28 +161,24 @@ export function reducePayloadSizeOrThrow(
error: Error, error: Error,
averageTokenLength = 4, averageTokenLength = 4,
) { ) {
try { let remainingTokensToReduce = calculateRemainingTokens(error);
let remainingTokensToReduce = calculateRemainingTokens(error);
const [remaining, parentNodesTokenCount] = trimParentNodesSchema( const [remaining, parentNodesTokenCount] = trimParentNodesSchema(
payload, payload,
remainingTokensToReduce, remainingTokensToReduce,
averageTokenLength, averageTokenLength,
); );
remainingTokensToReduce = remaining; remainingTokensToReduce = remaining;
remainingTokensToReduce = trimInputSchemaProperties( remainingTokensToReduce = trimInputSchemaProperties(
payload, payload,
remainingTokensToReduce, remainingTokensToReduce,
averageTokenLength, averageTokenLength,
parentNodesTokenCount, parentNodesTokenCount,
); );
if (remainingTokensToReduce > 0) throw error; if (remainingTokensToReduce > 0) throw error;
} catch (e) {
throw e;
}
} }
export async function generateCodeForAiTransform(prompt: string, path: string, retries = 1) { export async function generateCodeForAiTransform(prompt: string, path: string, retries = 1) {

View file

@ -200,29 +200,25 @@ async function createExecutionPromise() {
} }
async function onRunChatWorkflow(payload: RunWorkflowChatPayload) { async function onRunChatWorkflow(payload: RunWorkflowChatPayload) {
try { const runWorkflowOptions: Parameters<typeof runWorkflow>[0] = {
const runWorkflowOptions: Parameters<typeof runWorkflow>[0] = { triggerNode: payload.triggerNode,
triggerNode: payload.triggerNode, nodeData: payload.nodeData,
nodeData: payload.nodeData, source: payload.source,
source: payload.source, };
};
if (workflowsStore.chatPartialExecutionDestinationNode) { if (workflowsStore.chatPartialExecutionDestinationNode) {
runWorkflowOptions.destinationNode = workflowsStore.chatPartialExecutionDestinationNode; runWorkflowOptions.destinationNode = workflowsStore.chatPartialExecutionDestinationNode;
workflowsStore.chatPartialExecutionDestinationNode = null; workflowsStore.chatPartialExecutionDestinationNode = null;
}
const response = await runWorkflow(runWorkflowOptions);
if (response) {
await createExecutionPromise();
workflowsStore.appendChatMessage(payload.message);
return response;
}
return;
} catch (error) {
throw error;
} }
const response = await runWorkflow(runWorkflowOptions);
if (response) {
await createExecutionPromise();
workflowsStore.appendChatMessage(payload.message);
return response;
}
return;
} }
// Initialize chat config // Initialize chat config

View file

@ -55,21 +55,13 @@ export const useCommunityNodesStore = defineStore(STORES.COMMUNITY_NODES, () =>
}; };
const installPackage = async (packageName: string): Promise<void> => { const installPackage = async (packageName: string): Promise<void> => {
try { await communityNodesApi.installNewPackage(rootStore.restApiContext, packageName);
await communityNodesApi.installNewPackage(rootStore.restApiContext, packageName); await fetchInstalledPackages();
await fetchInstalledPackages();
} catch (error) {
throw error;
}
}; };
const uninstallPackage = async (packageName: string): Promise<void> => { const uninstallPackage = async (packageName: string): Promise<void> => {
try { await communityNodesApi.uninstallPackage(rootStore.restApiContext, packageName);
await communityNodesApi.uninstallPackage(rootStore.restApiContext, packageName); removePackageByName(packageName);
removePackageByName(packageName);
} catch (error) {
throw error;
}
}; };
const removePackageByName = (name: string): void => { const removePackageByName = (name: string): void => {
@ -82,16 +74,12 @@ export const useCommunityNodesStore = defineStore(STORES.COMMUNITY_NODES, () =>
}; };
const updatePackage = async (packageName: string): Promise<void> => { const updatePackage = async (packageName: string): Promise<void> => {
try { const packageToUpdate = installedPackages.value[packageName];
const packageToUpdate = installedPackages.value[packageName]; const updatedPackage = await communityNodesApi.updatePackage(
const updatedPackage = await communityNodesApi.updatePackage( rootStore.restApiContext,
rootStore.restApiContext, packageToUpdate.packageName,
packageToUpdate.packageName, );
); updatePackageObject(updatedPackage);
updatePackageObject(updatedPackage);
} catch (error) {
throw error;
}
}; };
return { return {

View file

@ -173,8 +173,6 @@ export const useExecutionsStore = defineStore('executions', () => {
executionsCount.value = data.count; executionsCount.value = data.count;
executionsCountEstimated.value = data.estimated; executionsCountEstimated.value = data.estimated;
return data; return data;
} catch (e) {
throw e;
} finally { } finally {
loading.value = false; loading.value = false;
} }

View file

@ -601,16 +601,12 @@ export class Disqus implements INodeType {
Object.assign(qs, additionalFields); Object.assign(qs, additionalFields);
try { const responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint);
const responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint); const executionData = this.helpers.constructExecutionMetaData(
const executionData = this.helpers.constructExecutionMetaData( this.helpers.returnJsonArray(responseData.response as IDataObject[]),
this.helpers.returnJsonArray(responseData.response as IDataObject[]), { itemData: { item: i } },
{ itemData: { item: i } }, );
); returnData.push(...executionData);
returnData.push(...executionData);
} catch (error) {
throw error;
}
} else if (operation === 'getPosts') { } else if (operation === 'getPosts') {
// ---------------------------------- // ----------------------------------
// getPosts // getPosts
@ -629,28 +625,24 @@ export class Disqus implements INodeType {
qs.forum = id; qs.forum = id;
qs.limit = 100; qs.limit = 100;
try { let responseData: IDataObject = {};
let responseData: IDataObject = {}; if (returnAll) {
if (returnAll) { responseData.response = await disqusApiRequestAllItems.call(
responseData.response = await disqusApiRequestAllItems.call( this,
this, requestMethod,
requestMethod, qs,
qs, endpoint,
endpoint,
);
} else {
const limit = this.getNodeParameter('limit', i);
qs.limit = limit;
responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint);
}
const executionData = this.helpers.constructExecutionMetaData(
this.helpers.returnJsonArray(responseData.response as IDataObject),
{ itemData: { item: i } },
); );
returnData.push(...executionData); } else {
} catch (error) { const limit = this.getNodeParameter('limit', i);
throw error; qs.limit = limit;
responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint);
} }
const executionData = this.helpers.constructExecutionMetaData(
this.helpers.returnJsonArray(responseData.response as IDataObject),
{ itemData: { item: i } },
);
returnData.push(...executionData);
} else if (operation === 'getCategories') { } else if (operation === 'getCategories') {
// ---------------------------------- // ----------------------------------
// getCategories // getCategories
@ -668,34 +660,30 @@ export class Disqus implements INodeType {
qs.forum = id; qs.forum = id;
qs.limit = 100; qs.limit = 100;
try { let responseData: IDataObject = {};
let responseData: IDataObject = {};
if (returnAll) { if (returnAll) {
responseData.response = await disqusApiRequestAllItems.call( responseData.response = await disqusApiRequestAllItems.call(
this, this,
requestMethod, requestMethod,
qs, qs,
endpoint, endpoint,
);
} else {
const limit = this.getNodeParameter('limit', i);
qs.limit = limit;
responseData = (await disqusApiRequest.call(
this,
requestMethod,
qs,
endpoint,
)) as IDataObject;
}
const executionData = this.helpers.constructExecutionMetaData(
this.helpers.returnJsonArray(responseData.response as IDataObject),
{ itemData: { item: i } },
); );
returnData.push(...executionData); } else {
} catch (error) { const limit = this.getNodeParameter('limit', i);
throw error; qs.limit = limit;
responseData = (await disqusApiRequest.call(
this,
requestMethod,
qs,
endpoint,
)) as IDataObject;
} }
const executionData = this.helpers.constructExecutionMetaData(
this.helpers.returnJsonArray(responseData.response as IDataObject),
{ itemData: { item: i } },
);
returnData.push(...executionData);
} else if (operation === 'getThreads') { } else if (operation === 'getThreads') {
// ---------------------------------- // ----------------------------------
// getThreads // getThreads
@ -715,28 +703,24 @@ export class Disqus implements INodeType {
Object.assign(qs, additionalFields); Object.assign(qs, additionalFields);
try { let responseData: IDataObject = {};
let responseData: IDataObject = {}; if (returnAll) {
if (returnAll) { responseData.response = await disqusApiRequestAllItems.call(
responseData.response = await disqusApiRequestAllItems.call( this,
this, requestMethod,
requestMethod, qs,
qs, endpoint,
endpoint,
);
} else {
const limit = this.getNodeParameter('limit', i);
qs.limit = limit;
responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint);
}
const executionData = this.helpers.constructExecutionMetaData(
this.helpers.returnJsonArray(responseData.response as IDataObject),
{ itemData: { item: i } },
); );
returnData.push(...executionData); } else {
} catch (error) { const limit = this.getNodeParameter('limit', i);
throw error; qs.limit = limit;
responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint);
} }
const executionData = this.helpers.constructExecutionMetaData(
this.helpers.returnJsonArray(responseData.response as IDataObject),
{ itemData: { item: i } },
);
returnData.push(...executionData);
} else { } else {
throw new NodeOperationError( throw new NodeOperationError(
this.getNode(), this.getNode(),

View file

@ -66,14 +66,10 @@ export async function disqusApiRequestAllItems(
let responseData; let responseData;
try { do {
do { responseData = await disqusApiRequest.call(this, method, qs, uri, body, option);
responseData = await disqusApiRequest.call(this, method, qs, uri, body, option); qs.cursor = responseData.cursor.id;
qs.cursor = responseData.cursor.id; returnData.push.apply(returnData, responseData.response as IDataObject[]);
returnData.push.apply(returnData, responseData.response as IDataObject[]); } while (responseData.cursor.more === true && responseData.cursor.hasNext === true);
} while (responseData.cursor.more === true && responseData.cursor.hasNext === true); return returnData;
return returnData;
} catch (error) {
throw error;
}
} }

View file

@ -154,13 +154,8 @@ export async function getFields(this: ILoadOptionsFunctions): Promise<any> {
json: true, json: true,
}; };
try { const responseData = await this.helpers.request(options);
const responseData = await this.helpers.request(options); return responseData.response.fieldMetaData;
return responseData.response.fieldMetaData;
} catch (error) {
// If that data does not exist for some reason return the actual error
throw error;
}
} }
/** /**
@ -185,13 +180,8 @@ export async function getPortals(this: ILoadOptionsFunctions): Promise<any> {
json: true, json: true,
}; };
try { const responseData = await this.helpers.request(options);
const responseData = await this.helpers.request(options); return responseData.response.portalMetaData;
return responseData.response.portalMetaData;
} catch (error) {
// If that data does not exist for some reason return the actual error
throw error;
}
} }
function parseScriptsList(scripts: ScriptObject[]): INodePropertyOptions[] { function parseScriptsList(scripts: ScriptObject[]): INodePropertyOptions[] {
@ -230,15 +220,10 @@ export async function getScripts(this: ILoadOptionsFunctions): Promise<any> {
json: true, json: true,
}; };
try { const responseData = await this.helpers.request(options);
const responseData = await this.helpers.request(options); const items = parseScriptsList(responseData.response.scripts as ScriptObject[]);
const items = parseScriptsList(responseData.response.scripts as ScriptObject[]); items.sort((a, b) => (a.name > b.name ? 0 : 1));
items.sort((a, b) => (a.name > b.name ? 0 : 1)); return items;
return items;
} catch (error) {
// If that data does not exist for some reason return the actual error
throw error;
}
} }
export async function logout( export async function logout(

View file

@ -107,12 +107,8 @@ export class FlowTrigger implements INodeType {
} }
qs.organization_id = credentials.organizationId as number; qs.organization_id = credentials.organizationId as number;
const endpoint = '/integration_webhooks'; const endpoint = '/integration_webhooks';
try { webhooks = await flowApiRequest.call(this, 'GET', endpoint, {}, qs);
webhooks = await flowApiRequest.call(this, 'GET', endpoint, {}, qs); webhooks = webhooks.integration_webhooks;
webhooks = webhooks.integration_webhooks;
} catch (error) {
throw error;
}
for (const webhook of webhooks) { for (const webhook of webhooks) {
// @ts-ignore // @ts-ignore
if (webhookData.webhookIds.includes(webhook.id)) { if (webhookData.webhookIds.includes(webhook.id)) {

View file

@ -16,19 +16,15 @@ export async function router(this: IExecuteFunctions): Promise<INodeExecutionDat
operation, operation,
} as ItemListsType; } as ItemListsType;
try { switch (itemListsNodeData.resource) {
switch (itemListsNodeData.resource) { case 'itemList':
case 'itemList': returnData = await itemList[itemListsNodeData.operation].execute.call(this, items);
returnData = await itemList[itemListsNodeData.operation].execute.call(this, items); break;
break; default:
default: throw new NodeOperationError(
throw new NodeOperationError( this.getNode(),
this.getNode(), `The operation "${operation}" is not supported!`,
`The operation "${operation}" is not supported!`, );
);
}
} catch (error) {
throw error;
} }
return [returnData]; return [returnData];

View file

@ -214,7 +214,6 @@ export class MailchimpTrigger implements INodeType {
}, },
async create(this: IHookFunctions): Promise<boolean> { async create(this: IHookFunctions): Promise<boolean> {
let webhook;
const webhookUrl = this.getNodeWebhookUrl('default'); const webhookUrl = this.getNodeWebhookUrl('default');
const listId = this.getNodeParameter('list') as string; const listId = this.getNodeParameter('list') as string;
const events = this.getNodeParameter('events', []) as string[]; const events = this.getNodeParameter('events', []) as string[];
@ -233,11 +232,7 @@ export class MailchimpTrigger implements INodeType {
}, {}), }, {}),
}; };
const endpoint = `/lists/${listId}/webhooks`; const endpoint = `/lists/${listId}/webhooks`;
try { const webhook = await mailchimpApiRequest.call(this, endpoint, 'POST', body);
webhook = await mailchimpApiRequest.call(this, endpoint, 'POST', body);
} catch (error) {
throw error;
}
if (webhook.id === undefined) { if (webhook.id === undefined) {
return false; return false;
} }

View file

@ -115,7 +115,6 @@ export class PayPalTrigger implements INodeType {
}, },
async create(this: IHookFunctions): Promise<boolean> { async create(this: IHookFunctions): Promise<boolean> {
let webhook;
const webhookUrl = this.getNodeWebhookUrl('default'); const webhookUrl = this.getNodeWebhookUrl('default');
const events = this.getNodeParameter('events', []) as string[]; const events = this.getNodeParameter('events', []) as string[];
const body = { const body = {
@ -125,11 +124,7 @@ export class PayPalTrigger implements INodeType {
}), }),
}; };
const endpoint = '/notifications/webhooks'; const endpoint = '/notifications/webhooks';
try { const webhook = await payPalApiRequest.call(this, endpoint, 'POST', body);
webhook = await payPalApiRequest.call(this, endpoint, 'POST', body);
} catch (error) {
throw error;
}
if (webhook.id === undefined) { if (webhook.id === undefined) {
return false; return false;
@ -156,7 +151,6 @@ export class PayPalTrigger implements INodeType {
}; };
async webhook(this: IWebhookFunctions): Promise<IWebhookResponseData> { async webhook(this: IWebhookFunctions): Promise<IWebhookResponseData> {
let webhook;
const webhookData = this.getWorkflowStaticData('node'); const webhookData = this.getWorkflowStaticData('node');
const bodyData = this.getBodyData(); const bodyData = this.getBodyData();
const req = this.getRequestObject(); const req = this.getRequestObject();
@ -188,11 +182,7 @@ export class PayPalTrigger implements INodeType {
webhook_id: webhookData.webhookId, webhook_id: webhookData.webhookId,
webhook_event: bodyData, webhook_event: bodyData,
}; };
try { const webhook = await payPalApiRequest.call(this, endpoint, 'POST', body);
webhook = await payPalApiRequest.call(this, endpoint, 'POST', body);
} catch (error) {
throw error;
}
if (webhook.verification_status !== 'SUCCESS') { if (webhook.verification_status !== 'SUCCESS') {
return {}; return {};
} }

View file

@ -877,12 +877,7 @@ export class StripeTrigger implements INodeType {
enabled_events: events, enabled_events: events,
}; };
let responseData; const responseData = await stripeApiRequest.call(this, 'POST', endpoint, body);
try {
responseData = await stripeApiRequest.call(this, 'POST', endpoint, body);
} catch (error) {
throw error;
}
if ( if (
responseData.id === undefined || responseData.id === undefined ||

View file

@ -16,19 +16,15 @@ export async function router(this: IExecuteFunctions): Promise<INodeExecutionDat
operation, operation,
} as WebflowType; } as WebflowType;
try { switch (webflowNodeData.resource) {
switch (webflowNodeData.resource) { case 'item':
case 'item': returnData = await item[webflowNodeData.operation].execute.call(this, items);
returnData = await item[webflowNodeData.operation].execute.call(this, items); break;
break; default:
default: throw new NodeOperationError(
throw new NodeOperationError( this.getNode(),
this.getNode(), `The operation "${operation}" is not supported!`,
`The operation "${operation}" is not supported!`, );
);
}
} catch (error) {
throw error;
} }
return [returnData]; return [returnData];