mirror of
https://github.com/n8n-io/n8n.git
synced 2026-09-21 04:37:50 +08:00
fix(core): Acquire expression isolate when reconciling unregistered webhooks during publication (no-changelog) (#33341)
Co-authored-by: linear-code[bot] <222613912+linear-code[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
linear-code[bot]
parent
5cf8645a7c
commit
a5ac4259b8
@@ -167,6 +167,54 @@ describe('WorkflowTriggerActivator', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('brackets the registrar call with an acquired isolate so path expressions resolve', async () => {
|
||||
const callOrder: string[] = [];
|
||||
vi.spyOn(WorkflowExpression.prototype, 'acquireIsolate').mockImplementation(async () => {
|
||||
callOrder.push('acquire');
|
||||
});
|
||||
vi.spyOn(WorkflowExpression.prototype, 'releaseIsolate').mockImplementation(async () => {
|
||||
callOrder.push('release');
|
||||
});
|
||||
vi.spyOn(WorkflowExecuteAdditionalData, 'getBase').mockResolvedValue(
|
||||
mock<IWorkflowExecuteAdditionalData>(),
|
||||
);
|
||||
const webhookTriggerRegistrar = mock<WebhookTriggerRegistrar>();
|
||||
webhookTriggerRegistrar.getNodesWithUnregisteredWebhooks.mockImplementation(async () => {
|
||||
callOrder.push('resolve');
|
||||
return new Set(['w']);
|
||||
});
|
||||
const activator = buildActivator({ webhookTriggerRegistrar });
|
||||
|
||||
await activator.getNodesWithUnregisteredWebhooks(
|
||||
mock<WorkflowEntity>({ id: 'wf-1', name: 'Test workflow', staticData: {}, settings: {} }),
|
||||
{ nodes: [node('w', 'webhook')], connections: {} },
|
||||
);
|
||||
|
||||
expect(callOrder).toEqual(['acquire', 'resolve', 'release']);
|
||||
});
|
||||
|
||||
test('releases the isolate when the registrar throws', async () => {
|
||||
vi.spyOn(WorkflowExecuteAdditionalData, 'getBase').mockResolvedValue(
|
||||
mock<IWorkflowExecuteAdditionalData>(),
|
||||
);
|
||||
const releaseIsolate = vi
|
||||
.spyOn(WorkflowExpression.prototype, 'releaseIsolate')
|
||||
.mockResolvedValue(undefined);
|
||||
vi.spyOn(WorkflowExpression.prototype, 'acquireIsolate').mockResolvedValue(undefined);
|
||||
const webhookTriggerRegistrar = mock<WebhookTriggerRegistrar>();
|
||||
webhookTriggerRegistrar.getNodesWithUnregisteredWebhooks.mockRejectedValue(new Error('boom'));
|
||||
const activator = buildActivator({ webhookTriggerRegistrar });
|
||||
|
||||
await expect(
|
||||
activator.getNodesWithUnregisteredWebhooks(
|
||||
mock<WorkflowEntity>({ id: 'wf-1', name: 'Test workflow', staticData: {}, settings: {} }),
|
||||
{ nodes: [node('w', 'webhook')], connections: {} },
|
||||
),
|
||||
).rejects.toThrow('boom');
|
||||
|
||||
expect(releaseIsolate).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('returns empty without calling the registrar when there are no trigger nodes', async () => {
|
||||
const webhookTriggerRegistrar = mock<WebhookTriggerRegistrar>();
|
||||
const activator = buildActivator({ webhookTriggerRegistrar });
|
||||
|
||||
@@ -155,11 +155,18 @@ export class WorkflowTriggerActivator {
|
||||
workflowSettings: dbWorkflow.settings,
|
||||
});
|
||||
|
||||
return await this.webhookTriggerRegistrar.getNodesWithUnregisteredWebhooks(
|
||||
workflow,
|
||||
additionalData,
|
||||
desiredNodes,
|
||||
);
|
||||
// Resolving webhook triggers evaluates each node's `path`/`httpMethod`
|
||||
// expressions (e.g. the Form Trigger's dynamic path), which needs an isolate.
|
||||
await workflow.expression.acquireIsolate();
|
||||
try {
|
||||
return await this.webhookTriggerRegistrar.getNodesWithUnregisteredWebhooks(
|
||||
workflow,
|
||||
additionalData,
|
||||
desiredNodes,
|
||||
);
|
||||
} finally {
|
||||
await workflow.expression.releaseIsolate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user