mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
fix(core): Improve error message when resolving itemMatching with pinned data (no-changelog) (#12641)
This commit is contained in:
parent
05858c2153
commit
395f2ad0dc
|
@ -110,7 +110,10 @@ describe('NDV', () => {
|
|||
ndv.actions.execute();
|
||||
ndv.getters
|
||||
.nodeRunErrorMessage()
|
||||
.should('have.text', 'Info for expression missing from previous node');
|
||||
.should(
|
||||
'have.text',
|
||||
"Using the item method doesn't work with pinned data in this scenario. Please unpin 'Break pairedItem chain' and try again.",
|
||||
);
|
||||
ndv.getters
|
||||
.nodeRunErrorDescription()
|
||||
.should(
|
||||
|
|
|
@ -703,17 +703,19 @@ export class WorkflowDataProxy {
|
|||
});
|
||||
};
|
||||
|
||||
const createMissingPairedItemError = (nodeCause: string) => {
|
||||
return createExpressionError("Can't get data for expression", {
|
||||
messageTemplate: 'Info for expression missing from previous node',
|
||||
const createMissingPairedItemError = (
|
||||
nodeCause: string,
|
||||
usedMethodName: 'itemMatching' | 'pairedItem' | 'item' | '$getPairedItem' = 'pairedItem',
|
||||
) => {
|
||||
const message = `Using the ${usedMethodName} method doesn't work with pinned data in this scenario. Please unpin '${nodeCause}' and try again.`;
|
||||
return new ExpressionError(message, {
|
||||
runIndex: that.runIndex,
|
||||
itemIndex: that.itemIndex,
|
||||
functionality: 'pairedItem',
|
||||
functionOverrides: {
|
||||
message: "Can't get data",
|
||||
},
|
||||
nodeCause,
|
||||
descriptionKey: isScriptingNode(nodeCause, that.workflow)
|
||||
? 'pairedItemNoInfoCodeNode'
|
||||
: 'pairedItemNoInfo',
|
||||
nodeCause,
|
||||
causeDetailed: `Missing pairedItem data (node '${nodeCause}' probably didn't supply it)`,
|
||||
type: 'paired_item_no_info',
|
||||
});
|
||||
|
@ -737,6 +739,7 @@ export class WorkflowDataProxy {
|
|||
destinationNodeName: string,
|
||||
incomingSourceData: ISourceData | null,
|
||||
pairedItem: IPairedItemData,
|
||||
usedMethodName: 'pairedItem' | 'itemMatching' | 'item' | '$getPairedItem' = '$getPairedItem',
|
||||
): INodeExecutionData | null => {
|
||||
let taskData: ITaskData | undefined;
|
||||
|
||||
|
@ -790,7 +793,7 @@ export class WorkflowDataProxy {
|
|||
const itemPreviousNode: INodeExecutionData = previousNodeOutputData[pairedItem.item];
|
||||
|
||||
if (itemPreviousNode.pairedItem === undefined) {
|
||||
throw createMissingPairedItemError(sourceData.previousNode);
|
||||
throw createMissingPairedItemError(sourceData.previousNode, usedMethodName);
|
||||
}
|
||||
|
||||
if (Array.isArray(itemPreviousNode.pairedItem)) {
|
||||
|
@ -806,7 +809,7 @@ export class WorkflowDataProxy {
|
|||
throw new ApplicationError('Not found');
|
||||
}
|
||||
|
||||
return getPairedItem(destinationNodeName, source[itemInput], item);
|
||||
return getPairedItem(destinationNodeName, source[itemInput], item, usedMethodName);
|
||||
} catch (error) {
|
||||
// Means pairedItem could not be found
|
||||
return null;
|
||||
|
@ -858,6 +861,7 @@ export class WorkflowDataProxy {
|
|||
// A trigger node got reached, so looks like that that item can not be resolved
|
||||
throw createNoConnectionError(destinationNodeName);
|
||||
}
|
||||
|
||||
throw createExpressionError('Can’t get data for expression', {
|
||||
messageTemplate: 'Can’t get data for expression under ‘%%PARAMETER%%’ field',
|
||||
functionality: 'pairedItem',
|
||||
|
@ -1039,7 +1043,7 @@ export class WorkflowDataProxy {
|
|||
);
|
||||
}
|
||||
|
||||
if (['pairedItem', 'itemMatching', 'item'].includes(property as string)) {
|
||||
if (property === 'pairedItem' || property === 'itemMatching' || property === 'item') {
|
||||
// Before resolving the pairedItem make sure that the requested node comes in the
|
||||
// graph before the current one
|
||||
const activeNode = that.workflow.getNode(that.activeNodeName);
|
||||
|
@ -1101,7 +1105,7 @@ export class WorkflowDataProxy {
|
|||
const pairedItem = input.pairedItem as IPairedItemData;
|
||||
|
||||
if (pairedItem === undefined) {
|
||||
throw createMissingPairedItemError(that.activeNodeName);
|
||||
throw createMissingPairedItemError(that.activeNodeName, property);
|
||||
}
|
||||
|
||||
if (!that.executeData?.source) {
|
||||
|
@ -1122,7 +1126,7 @@ export class WorkflowDataProxy {
|
|||
that.executeData.source.main[pairedItem.input || 0] ??
|
||||
that.executeData.source.main[0];
|
||||
|
||||
return getPairedItem(nodeName, sourceData, pairedItem);
|
||||
return getPairedItem(nodeName, sourceData, pairedItem, property);
|
||||
};
|
||||
|
||||
if (property === 'item') {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { ensureError } from '@/errors/ensure-error';
|
||||
import { ExpressionError } from '@/errors/expression.error';
|
||||
import {
|
||||
NodeConnectionType,
|
||||
|
@ -334,7 +335,9 @@ describe('WorkflowDataProxy', () => {
|
|||
} catch (error) {
|
||||
expect(error).toBeInstanceOf(ExpressionError);
|
||||
const exprError = error as ExpressionError;
|
||||
expect(exprError.message).toEqual("Can't get data for expression");
|
||||
expect(exprError.message).toEqual(
|
||||
"Using the item method doesn't work with pinned data in this scenario. Please unpin 'Break pairedItem chain' and try again.",
|
||||
);
|
||||
expect(exprError.context.type).toEqual('paired_item_no_info');
|
||||
done();
|
||||
}
|
||||
|
@ -412,6 +415,66 @@ describe('WorkflowDataProxy', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('Pinned data with paired items', () => {
|
||||
const fixture = loadFixture('pindata_paireditem');
|
||||
const proxy = getProxyFromFixture(fixture.workflow, fixture.run, 'Set', 'manual', {
|
||||
runIndex: 0,
|
||||
throwOnMissingExecutionData: false,
|
||||
});
|
||||
|
||||
test.each([{ methodName: 'itemMatching' }, { methodName: 'pairedItem' }])(
|
||||
'$methodName should throw when it cannot find a paired item',
|
||||
async ({ methodName }) => {
|
||||
try {
|
||||
proxy.$('DebugHelper')[methodName](0);
|
||||
fail('should throw');
|
||||
} catch (e) {
|
||||
const error = ensureError(e);
|
||||
expect(error.message).toEqual(
|
||||
`Using the ${methodName} method doesn't work with pinned data in this scenario. Please unpin 'Edit Fields' and try again.`,
|
||||
);
|
||||
|
||||
expect(error).toMatchObject({
|
||||
functionality: 'pairedItem',
|
||||
context: {
|
||||
runIndex: 0,
|
||||
itemIndex: 0,
|
||||
type: 'paired_item_no_info',
|
||||
descriptionKey: 'pairedItemNoInfo',
|
||||
nodeCause: 'Edit Fields',
|
||||
causeDetailed:
|
||||
"Missing pairedItem data (node 'Edit Fields' probably didn't supply it)",
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
test('item should throw when it cannot find a paired item', async () => {
|
||||
try {
|
||||
proxy.$('DebugHelper').item;
|
||||
fail('should throw');
|
||||
} catch (e) {
|
||||
const error = ensureError(e);
|
||||
expect(error.message).toEqual(
|
||||
"Using the item method doesn't work with pinned data in this scenario. Please unpin 'Edit Fields' and try again.",
|
||||
);
|
||||
|
||||
expect(error).toMatchObject({
|
||||
functionality: 'pairedItem',
|
||||
context: {
|
||||
runIndex: 0,
|
||||
itemIndex: 0,
|
||||
type: 'paired_item_no_info',
|
||||
descriptionKey: 'pairedItemNoInfo',
|
||||
nodeCause: 'Edit Fields',
|
||||
causeDetailed: "Missing pairedItem data (node 'Edit Fields' probably didn't supply it)",
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('Partial data', () => {
|
||||
const fixture = loadFixture('partial_data');
|
||||
|
||||
|
|
216
packages/workflow/test/fixtures/WorkflowDataProxy/pindata_paireditem_run.json
vendored
Normal file
216
packages/workflow/test/fixtures/WorkflowDataProxy/pindata_paireditem_run.json
vendored
Normal file
|
@ -0,0 +1,216 @@
|
|||
{
|
||||
"data": {
|
||||
"startData": {},
|
||||
"resultData": {
|
||||
"runData": {
|
||||
"When clicking ‘Test workflow’": [
|
||||
{
|
||||
"hints": [],
|
||||
"startTime": 1737031584297,
|
||||
"executionTime": 1,
|
||||
"source": [],
|
||||
"executionStatus": "success",
|
||||
"data": { "main": [[{ "json": {}, "pairedItem": { "item": 0 } }]] }
|
||||
}
|
||||
],
|
||||
"DebugHelper": [
|
||||
{
|
||||
"hints": [],
|
||||
"startTime": 1737031584299,
|
||||
"executionTime": 1,
|
||||
"source": [{ "previousNode": "When clicking ‘Test workflow’" }],
|
||||
"executionStatus": "success",
|
||||
"data": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"json": {
|
||||
"uid": "3c54ac5d-5c75-409d-9975-76ee151e5fc9",
|
||||
"email": "Troy.Volkman@gmail.com",
|
||||
"firstname": "Betty",
|
||||
"lastname": "Wolf",
|
||||
"password": "c~837Nv"
|
||||
},
|
||||
"pairedItem": { "item": 0 }
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"uid": "5b0d9bd7-2ecf-47fb-b484-3eb1e76fa901",
|
||||
"email": "Martha.Moore@hotmail.com",
|
||||
"firstname": "Shannon",
|
||||
"lastname": "Champlin",
|
||||
"password": "48FF,6dnx"
|
||||
},
|
||||
"pairedItem": { "item": 0 }
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"uid": "76437ebe-d406-447a-ab89-3b10f5183480",
|
||||
"email": "Wanda_Witting@hotmail.com",
|
||||
"firstname": "Alma",
|
||||
"lastname": "Conn",
|
||||
"password": "6$G2R3nT"
|
||||
},
|
||||
"pairedItem": { "item": 0 }
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"Edit Fields": [
|
||||
{
|
||||
"hints": [],
|
||||
"startTime": 1737031584301,
|
||||
"executionTime": 0,
|
||||
"source": [{ "previousNode": "DebugHelper" }],
|
||||
"executionStatus": "success",
|
||||
"data": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"json": {
|
||||
"uid": "d42c6385-12f2-4486-92b5-eebd2e95d161",
|
||||
"email": "Joanna_Willms@yahoo.com",
|
||||
"firstname": "Laurie",
|
||||
"lastname": "Krajcik",
|
||||
"password": "k%Y2I9oq",
|
||||
"test": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"uid": "53fc09df-5463-4f48-9fda-6500b1b77c82",
|
||||
"email": "Elaine_Feeney@gmail.com",
|
||||
"firstname": "Tracy",
|
||||
"lastname": "Mraz",
|
||||
"password": "t48s3-r",
|
||||
"test": "1"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"Set": [
|
||||
{
|
||||
"hints": [],
|
||||
"startTime": 1737031584301,
|
||||
"executionTime": 0,
|
||||
"source": [{ "previousNode": "Edit Fields" }],
|
||||
"data": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"json": {
|
||||
"uid": "d42c6385-12f2-4486-92b5-eebd2e95d161",
|
||||
"email": "Joanna_Willms@yahoo.com",
|
||||
"firstname": "Laurie",
|
||||
"lastname": "Krajcik",
|
||||
"password": "k%Y2I9oq",
|
||||
"test": "1"
|
||||
},
|
||||
"pairedItem": {
|
||||
"item": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"uid": "53fc09df-5463-4f48-9fda-6500b1b77c82",
|
||||
"email": "Elaine_Feeney@gmail.com",
|
||||
"firstname": "Tracy",
|
||||
"lastname": "Mraz",
|
||||
"password": "t48s3-r",
|
||||
"test": "1"
|
||||
},
|
||||
"pairedItem": {
|
||||
"item": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"pinData": {
|
||||
"Edit Fields": [
|
||||
{
|
||||
"json": {
|
||||
"uid": "d42c6385-12f2-4486-92b5-eebd2e95d161",
|
||||
"email": "Joanna_Willms@yahoo.com",
|
||||
"firstname": "Laurie",
|
||||
"lastname": "Krajcik",
|
||||
"password": "k%Y2I9oq",
|
||||
"test": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"uid": "53fc09df-5463-4f48-9fda-6500b1b77c82",
|
||||
"email": "Elaine_Feeney@gmail.com",
|
||||
"firstname": "Tracy",
|
||||
"lastname": "Mraz",
|
||||
"password": "t48s3-r",
|
||||
"test": "1"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"lastNodeExecuted": "Set"
|
||||
},
|
||||
"executionData": {
|
||||
"contextData": {},
|
||||
"nodeExecutionStack": [
|
||||
{
|
||||
"node": {
|
||||
"parameters": {
|
||||
"mode": "runOnceForAllItems",
|
||||
"language": "javaScript",
|
||||
"jsCode": "for (let i = 0; i < $input.all().length; i++) { $(\"DebugHelper\").itemMatching(i) } return []",
|
||||
"notice": ""
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [720, 0],
|
||||
"id": "d4e8b6a2-cd73-452d-b5f0-986753f5dc4a",
|
||||
"name": "Set"
|
||||
},
|
||||
"data": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"json": {
|
||||
"uid": "d42c6385-12f2-4486-92b5-eebd2e95d161",
|
||||
"email": "Joanna_Willms@yahoo.com",
|
||||
"firstname": "Laurie",
|
||||
"lastname": "Krajcik",
|
||||
"password": "k%Y2I9oq",
|
||||
"test": "1"
|
||||
},
|
||||
"pairedItem": { "item": 0 }
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"uid": "53fc09df-5463-4f48-9fda-6500b1b77c82",
|
||||
"email": "Elaine_Feeney@gmail.com",
|
||||
"firstname": "Tracy",
|
||||
"lastname": "Mraz",
|
||||
"password": "t48s3-r",
|
||||
"test": "1"
|
||||
},
|
||||
"pairedItem": { "item": 1 }
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"source": { "main": [{ "previousNode": "Edit Fields" }] }
|
||||
}
|
||||
],
|
||||
"metadata": {},
|
||||
"waitingExecution": {},
|
||||
"waitingExecutionSource": {}
|
||||
}
|
||||
}
|
||||
}
|
106
packages/workflow/test/fixtures/WorkflowDataProxy/pindata_paireditem_workflow.json
vendored
Normal file
106
packages/workflow/test/fixtures/WorkflowDataProxy/pindata_paireditem_workflow.json
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
{
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [0, 0],
|
||||
"id": "df3ea0b2-913b-4736-a3c6-f61b35abd1e1",
|
||||
"name": "When clicking ‘Test workflow’"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"category": "randomData",
|
||||
"randomDataCount": 3
|
||||
},
|
||||
"type": "n8n-nodes-base.debugHelper",
|
||||
"typeVersion": 1,
|
||||
"position": [280, 0],
|
||||
"id": "e31f942c-876a-43ae-b883-0b7566d44750",
|
||||
"name": "DebugHelper"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "049c69e3-969d-4df9-bf93-e44c1da06ba1",
|
||||
"name": "test",
|
||||
"value": "1",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"includeOtherFields": true,
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.4,
|
||||
"position": [500, 0],
|
||||
"id": "eb20f04e-875f-4a2d-853c-f2e30014b821",
|
||||
"name": "Edit Fields"
|
||||
},
|
||||
{
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 2,
|
||||
"position": [720, 0],
|
||||
"id": "d4e8b6a2-cd73-452d-b5f0-986753f5dc4a",
|
||||
"name": "Set"
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"When clicking ‘Test workflow’": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "DebugHelper",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"DebugHelper": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"pinData": {
|
||||
"Edit Fields": [
|
||||
{
|
||||
"uid": "d42c6385-12f2-4486-92b5-eebd2e95d161",
|
||||
"email": "Joanna_Willms@yahoo.com",
|
||||
"firstname": "Laurie",
|
||||
"lastname": "Krajcik",
|
||||
"password": "k%Y2I9oq",
|
||||
"test": "1"
|
||||
},
|
||||
{
|
||||
"uid": "53fc09df-5463-4f48-9fda-6500b1b77c82",
|
||||
"email": "Elaine_Feeney@gmail.com",
|
||||
"firstname": "Tracy",
|
||||
"lastname": "Mraz",
|
||||
"password": "t48s3-r",
|
||||
"test": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue