feat(core): Remove all floating promises. Enforce @typescript-eslint/no-floating-promises (#6281)
This commit is contained in:
committed by
GitHub
parent
5d2f4746ea
commit
e046f656fe
@@ -3,7 +3,6 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
/* eslint-disable no-await-in-loop */
|
||||
/* eslint-disable no-restricted-syntax */
|
||||
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||
/* eslint-disable @typescript-eslint/no-shadow */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
@@ -306,8 +305,7 @@ export class ActiveWorkflowRunner {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const executionMode = 'webhook';
|
||||
// @ts-ignore
|
||||
WebhookHelpers.executeWebhook(
|
||||
void WebhookHelpers.executeWebhook(
|
||||
workflow,
|
||||
webhookData,
|
||||
workflowData,
|
||||
@@ -627,7 +625,7 @@ export class ActiveWorkflowRunner {
|
||||
): void => {
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
Logger.debug(`Received event to trigger execution for workflow "${workflow.name}"`);
|
||||
WorkflowHelpers.saveStaticData(workflow);
|
||||
void WorkflowHelpers.saveStaticData(workflow);
|
||||
const executePromise = this.runWorkflow(
|
||||
workflowData,
|
||||
node,
|
||||
@@ -638,14 +636,14 @@ export class ActiveWorkflowRunner {
|
||||
);
|
||||
|
||||
if (donePromise) {
|
||||
executePromise.then((executionId) => {
|
||||
void executePromise.then((executionId) => {
|
||||
this.activeExecutions
|
||||
.getPostExecutePromise(executionId)
|
||||
.then(donePromise.resolve)
|
||||
.catch(donePromise.reject);
|
||||
});
|
||||
} else {
|
||||
executePromise.catch(Logger.error);
|
||||
void executePromise.catch(Logger.error);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -684,7 +682,7 @@ export class ActiveWorkflowRunner {
|
||||
): void => {
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
Logger.debug(`Received trigger for workflow "${workflow.name}"`);
|
||||
WorkflowHelpers.saveStaticData(workflow);
|
||||
void WorkflowHelpers.saveStaticData(workflow);
|
||||
// eslint-disable-next-line id-denylist
|
||||
const executePromise = this.runWorkflow(
|
||||
workflowData,
|
||||
@@ -696,7 +694,7 @@ export class ActiveWorkflowRunner {
|
||||
);
|
||||
|
||||
if (donePromise) {
|
||||
executePromise.then((executionId) => {
|
||||
void executePromise.then((executionId) => {
|
||||
this.activeExecutions
|
||||
.getPostExecutePromise(executionId)
|
||||
.then(donePromise.resolve)
|
||||
|
||||
@@ -552,12 +552,12 @@ export class Server extends AbstractServer {
|
||||
|
||||
// Check for basic auth credentials if activated
|
||||
if (config.getEnv('security.basicAuth.active')) {
|
||||
await setupBasicAuth(this.app, config, authIgnoreRegex);
|
||||
setupBasicAuth(this.app, config, authIgnoreRegex);
|
||||
}
|
||||
|
||||
// Check for and validate JWT if configured
|
||||
if (config.getEnv('security.jwtAuth.active')) {
|
||||
await setupExternalJWTAuth(this.app, config, authIgnoreRegex);
|
||||
setupExternalJWTAuth(this.app, config, authIgnoreRegex);
|
||||
}
|
||||
|
||||
// ----------------------------------------
|
||||
|
||||
@@ -272,8 +272,7 @@ export class TestWebhooks {
|
||||
|
||||
if (!foundWebhook) {
|
||||
// As it removes all webhooks of the workflow execute only once
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
activeWebhooks.removeWorkflow(workflow);
|
||||
void activeWebhooks.removeWorkflow(workflow);
|
||||
}
|
||||
|
||||
foundWebhook = true;
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
import {
|
||||
ErrorReporterProxy as ErrorReporter,
|
||||
LoggerProxy as Logger,
|
||||
@@ -40,10 +38,10 @@ export class WaitTracker {
|
||||
constructor() {
|
||||
// Poll every 60 seconds a list of upcoming executions
|
||||
this.mainTimer = setInterval(() => {
|
||||
this.getWaitingExecutions();
|
||||
void this.getWaitingExecutions();
|
||||
}, 60000);
|
||||
|
||||
this.getWaitingExecutions();
|
||||
void this.getWaitingExecutions();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
|
||||
@@ -130,8 +130,7 @@ export class WaitingWebhooks {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const executionMode = 'webhook';
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
WebhookHelpers.executeWebhook(
|
||||
void WebhookHelpers.executeWebhook(
|
||||
workflow,
|
||||
webhookData,
|
||||
workflowData as IWorkflowDb,
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||
/* eslint-disable @typescript-eslint/no-shadow */
|
||||
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/prefer-optional-chain */
|
||||
/* eslint-disable no-param-reassign */
|
||||
@@ -75,8 +74,7 @@ export class WorkflowRunner {
|
||||
* The process did send a hook message so execute the appropriate hook
|
||||
*/
|
||||
processHookMessage(workflowHooks: WorkflowHooks, hookData: IProcessMessageDataHook) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
workflowHooks.executeHookFunctions(hookData.hook, hookData.parameters);
|
||||
void workflowHooks.executeHookFunctions(hookData.hook, hookData.parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -305,11 +303,8 @@ export class WorkflowRunner {
|
||||
error,
|
||||
error.node,
|
||||
);
|
||||
additionalData.hooks
|
||||
.executeHookFunctions('workflowExecuteAfter', [failedExecution])
|
||||
.then(() => {
|
||||
this.activeExecutions.remove(executionId, failedExecution);
|
||||
});
|
||||
await additionalData.hooks.executeHookFunctions('workflowExecuteAfter', [failedExecution]);
|
||||
this.activeExecutions.remove(executionId, failedExecution);
|
||||
return executionId;
|
||||
}
|
||||
|
||||
@@ -382,7 +377,7 @@ export class WorkflowRunner {
|
||||
if (workflowTimeout > 0) {
|
||||
const timeout = Math.min(workflowTimeout, config.getEnv('executions.maxTimeout')) * 1000; // as seconds
|
||||
executionTimeout = setTimeout(() => {
|
||||
this.activeExecutions.stopExecution(executionId, 'timeout');
|
||||
void this.activeExecutions.stopExecution(executionId, 'timeout');
|
||||
}, timeout);
|
||||
}
|
||||
|
||||
@@ -395,15 +390,15 @@ export class WorkflowRunner {
|
||||
fullRunData.status = this.activeExecutions.getStatus(executionId);
|
||||
this.activeExecutions.remove(executionId, fullRunData);
|
||||
})
|
||||
.catch((error) => {
|
||||
.catch(async (error) =>
|
||||
this.processError(
|
||||
error,
|
||||
new Date(),
|
||||
data.executionMode,
|
||||
executionId,
|
||||
additionalData.hooks,
|
||||
);
|
||||
});
|
||||
),
|
||||
);
|
||||
} catch (error) {
|
||||
await this.processError(
|
||||
error,
|
||||
@@ -467,7 +462,7 @@ export class WorkflowRunner {
|
||||
|
||||
// Normally also workflow should be supplied here but as it only used for sending
|
||||
// data to editor-UI is not needed.
|
||||
hooks.executeHookFunctions('workflowExecuteBefore', []);
|
||||
await hooks.executeHookFunctions('workflowExecuteBefore', []);
|
||||
} catch (error) {
|
||||
// We use "getWorkflowHooksWorkerExecuter" as "getWorkflowHooksWorkerMain" does not contain the
|
||||
// "workflowExecuteAfter" which we require.
|
||||
@@ -585,7 +580,7 @@ export class WorkflowRunner {
|
||||
this.activeExecutions.remove(executionId, runData);
|
||||
// Normally also static data should be supplied here but as it only used for sending
|
||||
// data to editor-UI is not needed.
|
||||
hooks.executeHookFunctions('workflowExecuteAfter', [runData]);
|
||||
await hooks.executeHookFunctions('workflowExecuteAfter', [runData]);
|
||||
try {
|
||||
// Check if this execution data has to be removed from database
|
||||
// based on workflow settings.
|
||||
@@ -668,7 +663,7 @@ export class WorkflowRunner {
|
||||
let workflowTimeout = workflowSettings.executionTimeout ?? config.getEnv('executions.timeout'); // initialize with default
|
||||
|
||||
const processTimeoutFunction = (timeout: number) => {
|
||||
this.activeExecutions.stopExecution(executionId, 'timeout');
|
||||
void this.activeExecutions.stopExecution(executionId, 'timeout');
|
||||
executionTimeout = setTimeout(() => subprocess.kill(), Math.max(timeout * 0.2, 5000)); // minimum 5 seconds
|
||||
};
|
||||
|
||||
@@ -732,7 +727,7 @@ export class WorkflowRunner {
|
||||
const timeoutError = new WorkflowOperationError('Workflow execution timed out!');
|
||||
|
||||
// No need to add hook here as the subprocess takes care of calling the hooks
|
||||
this.processError(timeoutError, startedAt, data.executionMode, executionId);
|
||||
await this.processError(timeoutError, startedAt, data.executionMode, executionId);
|
||||
} else if (message.type === 'startExecution') {
|
||||
const executionId = await this.activeExecutions.add(message.data.runData);
|
||||
childExecutionIds.push(executionId);
|
||||
|
||||
@@ -497,8 +497,7 @@ process.on('message', async (message: IProcessMessage) => {
|
||||
status: 'canceled',
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
workflowRunner.sendHookToParentProcess('workflowExecuteAfter', [runData]);
|
||||
await workflowRunner.sendHookToParentProcess('workflowExecuteAfter', [runData]);
|
||||
}
|
||||
|
||||
await sendToParentProcess(message.type === 'timeout' ? message.type : 'end', {
|
||||
|
||||
@@ -282,7 +282,6 @@ export class Start extends BaseCommand {
|
||||
if (dbType === 'sqlite') {
|
||||
const shouldRunVacuum = config.getEnv('database.sqlite.executeVacuumOnStartup');
|
||||
if (shouldRunVacuum) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
await Db.collections.Execution.query('VACUUM;');
|
||||
}
|
||||
}
|
||||
@@ -360,8 +359,7 @@ export class Start extends BaseCommand {
|
||||
this.openBrowser();
|
||||
} else if (key.charCodeAt(0) === 3) {
|
||||
// Ctrl + c got pressed
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.stopProcess();
|
||||
void this.stopProcess();
|
||||
} else {
|
||||
// When anything else got pressed, record it and send it on enter into the child process
|
||||
// eslint-disable-next-line no-lonely-if
|
||||
|
||||
@@ -51,8 +51,7 @@ export class Worker extends BaseCommand {
|
||||
LoggerProxy.info('Stopping n8n...');
|
||||
|
||||
// Stop accepting new jobs
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
Worker.jobQueue.pause(true);
|
||||
await Worker.jobQueue.pause(true);
|
||||
|
||||
try {
|
||||
await this.externalHooks.run('n8n.stop', []);
|
||||
@@ -239,8 +238,9 @@ export class Worker extends BaseCommand {
|
||||
const queue = Container.get(Queue);
|
||||
await queue.init();
|
||||
Worker.jobQueue = queue.getBullObjectInstance();
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
Worker.jobQueue.process(flags.concurrency, async (job) => this.runJob(job, this.nodeTypes));
|
||||
void Worker.jobQueue.process(flags.concurrency, async (job) =>
|
||||
this.runJob(job, this.nodeTypes),
|
||||
);
|
||||
|
||||
this.logger.info('\nn8n worker is now ready');
|
||||
this.logger.info(` * Version: ${N8N_VERSION}`);
|
||||
|
||||
@@ -6,7 +6,7 @@ import { compare } from 'bcryptjs';
|
||||
import type { Config } from '@/config';
|
||||
import { basicAuthAuthorizationError } from '@/ResponseHelper';
|
||||
|
||||
export const setupBasicAuth = async (app: Application, config: Config, authIgnoreRegex: RegExp) => {
|
||||
export const setupBasicAuth = (app: Application, config: Config, authIgnoreRegex: RegExp) => {
|
||||
const basicAuthUser = config.getEnv('security.basicAuth.user');
|
||||
if (basicAuthUser === '') {
|
||||
throw new Error('Basic auth is activated but no user got defined. Please set one!');
|
||||
|
||||
@@ -4,11 +4,7 @@ import jwks from 'jwks-rsa';
|
||||
import type { Config } from '@/config';
|
||||
import { jwtAuthAuthorizationError } from '@/ResponseHelper';
|
||||
|
||||
export const setupExternalJWTAuth = async (
|
||||
app: Application,
|
||||
config: Config,
|
||||
authIgnoreRegex: RegExp,
|
||||
) => {
|
||||
export const setupExternalJWTAuth = (app: Application, config: Config, authIgnoreRegex: RegExp) => {
|
||||
const jwtAuthHeader = config.getEnv('security.jwtAuth.jwtHeader');
|
||||
if (jwtAuthHeader === '') {
|
||||
throw new Error('JWT auth is activated but no request header was defined. Please set one!');
|
||||
|
||||
Reference in New Issue
Block a user