fix(core): Resolves response promise for active execution on job finished in queue mode (#15643)

Co-authored-by: Jaakko Husso <jaakko@n8n.io>
This commit is contained in:
Guillaume Jacquart
2025-06-04 10:25:00 +02:00
committed by GitHub
parent 92cf3cedbb
commit 7cd7883b34
4 changed files with 44 additions and 4 deletions

View File

@@ -305,6 +305,7 @@ export class ScalingService {
this.activeExecutions.resolveResponsePromise(msg.executionId, decodedResponse);
break;
case 'job-finished':
this.activeExecutions.resolveResponsePromise(msg.executionId, {});
this.logger.info(`Execution ${msg.executionId} (job ${jobId}) finished successfully`, {
workerId: msg.workerId,
executionId: msg.executionId,

View File

@@ -65,6 +65,24 @@ describe('autoDetectResponseMode', () => {
expect(result).toBe('responseNode');
});
test('should return formPage when start node is FORM_NODE_TYPE and method is POST and there is a following FORM_NODE_TYPE node', () => {
const workflowStartNode = mock<INode>({
type: FORM_NODE_TYPE,
name: 'startNode',
parameters: {},
});
workflow.getChildNodes.mockReturnValue(['childNode']);
workflow.nodes.childNode = mock<INode>({
type: FORM_NODE_TYPE,
parameters: {
operation: 'completion',
},
disabled: false,
});
const result = autoDetectResponseMode(workflowStartNode, workflow, 'POST');
expect(result).toBe('formPage');
});
test('should return undefined when start node is FORM_NODE_TYPE with no other form child nodes', () => {
const workflowStartNode = mock<INode>({
type: FORM_NODE_TYPE,

View File

@@ -105,6 +105,7 @@ export function getWorkflowWebhooks(
return returnData;
}
// eslint-disable-next-line complexity
export function autoDetectResponseMode(
workflowStartNode: INode,
workflow: Workflow,
@@ -126,6 +127,21 @@ export function autoDetectResponseMode(
}
}
// If there are form nodes connected to a current form node we're dealing with a multipage form
// and we need to return the formPage response mode when a second page of the form gets submitted
// to be able to show potential form errors correctly.
if (workflowStartNode.type === FORM_NODE_TYPE && method === 'POST') {
const connectedNodes = workflow.getChildNodes(workflowStartNode.name);
for (const nodeName of connectedNodes) {
const node = workflow.nodes[nodeName];
if (node.type === FORM_NODE_TYPE && !node.disabled) {
return 'formPage';
}
}
}
if (workflowStartNode.type === WAIT_NODE_TYPE && workflowStartNode.parameters.resume !== 'form') {
return undefined;
}

View File

@@ -857,9 +857,7 @@
document.querySelector('#submit-btn span').style.display = 'inline-block';
let postUrl = '';
if (window.location.href.includes('form-waiting')) {
intervalId = setTimeout(checkExecutionStatus, interval);
} else {
if (!window.location.href.includes('form-waiting')) {
postUrl = window.location.search;
}
@@ -880,7 +878,8 @@
if(json?.formWaitingUrl) {
formWaitingUrl = json.formWaitingUrl;
intervalId = setTimeout(checkExecutionStatus, interval);
clearTimeout(timeoutId);
timeoutId = setTimeout(checkExecutionStatus, interval);
return;
}
@@ -934,6 +933,12 @@
})
.catch(function (error) {
console.error('Error:', error);
})
.finally(() => {
if (window.location.href.includes('form-waiting')) {
clearTimeout(timeoutId);
timeoutId = setTimeout(checkExecutionStatus, interval);
}
});
}
});