From c5e2d2dddcea53c9896113e41eb66ca4d01e124b Mon Sep 17 00:00:00 2001 From: Dana <152518854+dana-gill@users.noreply.github.com> Date: Mon, 31 Mar 2025 16:47:50 +0200 Subject: [PATCH] fix(Google Sheets Node): Improve error message when row_number is null or undefined (#14229) --- .../Google/Sheet/test/v2/node/update.test.ts | 42 +++++++++++++++++++ .../v2/actions/sheet/update.operation.ts | 11 ++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/packages/nodes-base/nodes/Google/Sheet/test/v2/node/update.test.ts b/packages/nodes-base/nodes/Google/Sheet/test/v2/node/update.test.ts index 35d8245698..3694c35618 100644 --- a/packages/nodes-base/nodes/Google/Sheet/test/v2/node/update.test.ts +++ b/packages/nodes-base/nodes/Google/Sheet/test/v2/node/update.test.ts @@ -204,4 +204,46 @@ describe('Google Sheet - Update', () => { 'USER_ENTERED', ); }); + + describe('row_number input error', () => { + it.each([{ rowNumber: undefined }, { rowNumber: null }])( + 'displays a helpful error message when row_number is $rowNumber', + async ({ rowNumber }) => { + mockExecuteFunctions.getInputData.mockReturnValueOnce([ + { + json: { + row_number: rowNumber, + name: 'name', + text: 'txt', + }, + pairedItem: { + item: 0, + input: undefined, + }, + }, + ]); + + mockExecuteFunctions.getNodeParameter.mockImplementation((parameterName: string) => { + const params: { [key: string]: string | object } = { + options: {}, + 'options.cellFormat': 'USER_ENTERED', + 'columns.matchingColumns': ['row_number'], + 'columns.value': { + row_number: rowNumber, // TODO: Test for undefined + }, + dataMode: 'defineBelow', + }; + return params[parameterName]; + }); + + mockGoogleSheet.getData.mockResolvedValueOnce([['macarena'], ['boomboom']]); + + mockGoogleSheet.getColumnValues.mockResolvedValueOnce([]); + + await expect(execute.call(mockExecuteFunctions, mockGoogleSheet, 'Sheet1')).rejects.toThrow( + 'Column to match on (row_number) is not defined. Since the field is used to determine the row to update, it needs to have a value set.', + ); + }, + ); + }); }); diff --git a/packages/nodes-base/nodes/Google/Sheet/v2/actions/sheet/update.operation.ts b/packages/nodes-base/nodes/Google/Sheet/v2/actions/sheet/update.operation.ts index c457832d6e..1a5b52c2ac 100644 --- a/packages/nodes-base/nodes/Google/Sheet/v2/actions/sheet/update.operation.ts +++ b/packages/nodes-base/nodes/Google/Sheet/v2/actions/sheet/update.operation.ts @@ -1,5 +1,5 @@ import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; +import { NodeOperationError, UserError } from 'n8n-workflow'; import { cellFormat, handlingExtraData, locationDefine } from './commonDescription'; import type { GoogleSheet } from '../../helpers/GoogleSheet'; @@ -369,6 +369,15 @@ export async function execute( } // Setting empty values to empty string so that they are not ignored by the API Object.keys(mappingValues).forEach((key) => { + if ( + key === 'row_number' && + (mappingValues[key] === null || mappingValues[key] === undefined) + ) { + throw new UserError( + 'Column to match on (row_number) is not defined. Since the field is used to determine the row to update, it needs to have a value set.', + ); + } + if (mappingValues[key] === undefined || mappingValues[key] === null) { mappingValues[key] = ''; }