From 732c8fcf8488fc35839855499f75202436fc4c9a Mon Sep 17 00:00:00 2001 From: Bryce Sheehan Date: Sun, 10 Jul 2022 17:10:50 +0800 Subject: [PATCH] feat(AWS DynamoDB Node): Improve error handling + add optional GetAll Scan FilterExpression (#3318) * FilterExpression, ExpressionAttributeValues optional * Returns AWS JSON messages not in response body * :hammer: fixed filterExpression missing in request body * :zap: linter fixes * Reintroduced 'fix' block at :311 results in duplication * :zap: lock file fix * :zap: fix Co-authored-by: Michael Kret --- .../nodes/Aws/DynamoDB/AwsDynamoDB.node.ts | 12 ++++++++++-- .../nodes/Aws/DynamoDB/GenericFunctions.ts | 2 +- .../nodes-base/nodes/Aws/DynamoDB/ItemDescription.ts | 9 ++++----- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/nodes-base/nodes/Aws/DynamoDB/AwsDynamoDB.node.ts b/packages/nodes-base/nodes/Aws/DynamoDB/AwsDynamoDB.node.ts index c10e8c7bc60cc..e55eb7a11a6b7 100644 --- a/packages/nodes-base/nodes/Aws/DynamoDB/AwsDynamoDB.node.ts +++ b/packages/nodes-base/nodes/Aws/DynamoDB/AwsDynamoDB.node.ts @@ -307,11 +307,13 @@ export class AwsDynamoDB implements INodeType { const body: IRequestBody = { TableName: this.getNodeParameter('tableName', i) as string, - ExpressionAttributeValues: adjustExpressionAttributeValues(eavUi), }; if (scan === true) { - body['FilterExpression'] = this.getNodeParameter('filterExpression', i) as string; + const filterExpression = this.getNodeParameter('filterExpression', i) as string; + if (filterExpression) { + body['FilterExpression'] = filterExpression; + } } else { body['KeyConditionExpression'] = this.getNodeParameter('keyConditionExpression', i) as string; } @@ -332,6 +334,12 @@ export class AwsDynamoDB implements INodeType { body.ExpressionAttributeNames = expressionAttributeName; } + const expressionAttributeValues = adjustExpressionAttributeValues(eavUi); + + if (Object.keys(expressionAttributeValues).length) { + body.ExpressionAttributeValues = expressionAttributeValues; + } + if (indexName) { body.IndexName = indexName; } diff --git a/packages/nodes-base/nodes/Aws/DynamoDB/GenericFunctions.ts b/packages/nodes-base/nodes/Aws/DynamoDB/GenericFunctions.ts index cb25ca70307a4..b39ede5ed6cfb 100644 --- a/packages/nodes-base/nodes/Aws/DynamoDB/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Aws/DynamoDB/GenericFunctions.ts @@ -59,7 +59,7 @@ export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | I try { return JSON.parse(await this.helpers.request!(options)); } catch (error) { - const errorMessage = (error.response && error.response.body.message) || (error.response && error.response.body.Message) || error.message; + const errorMessage = (error.response && error.response.body && error.response.body.message) || (error.response && error.response.body && error.response.body.Message) || error.message; if (error.statusCode === 403) { if (errorMessage === 'The security token included in the request is invalid.') { throw new Error('The AWS credentials are not valid!'); diff --git a/packages/nodes-base/nodes/Aws/DynamoDB/ItemDescription.ts b/packages/nodes-base/nodes/Aws/DynamoDB/ItemDescription.ts index d3ae6ea64792a..4423b61ad86ee 100644 --- a/packages/nodes-base/nodes/Aws/DynamoDB/ItemDescription.ts +++ b/packages/nodes-base/nodes/Aws/DynamoDB/ItemDescription.ts @@ -350,7 +350,7 @@ export const itemFields: INodeProperties[] = [ ], }, ], - description: 'Item\'s primary key. For example, with a simple primary key, you only need to provide a value for the partition key. For a composite primary key, you must provide values for both the partition key and the sort key', + description: 'Item\'s primary key. For example, with a simple primary key, you only need to provide a value for the partition key. For a composite primary key, you must provide values for both the partition key and the sort key.', }, { displayName: 'Simplify', @@ -593,7 +593,7 @@ export const itemFields: INodeProperties[] = [ ], }, ], - description: 'Item\'s primary key. For example, with a simple primary key, you only need to provide a value for the partition key. For a composite primary key, you must provide values for both the partition key and the sort key', + description: 'Item\'s primary key. For example, with a simple primary key, you only need to provide a value for the partition key. For a composite primary key, you must provide values for both the partition key and the sort key.', }, { displayName: 'Additional Fields', @@ -695,7 +695,6 @@ export const itemFields: INodeProperties[] = [ displayName: 'Filter Expression', name: 'filterExpression', type: 'string', - required: true, displayOptions: { show: { scan: [ @@ -704,7 +703,7 @@ export const itemFields: INodeProperties[] = [ }, }, default: '', - description: 'A filter expression determines which items within the Scan results should be returned to you. All of the other results are discarded.', + description: 'A filter expression determines which items within the Scan results should be returned to you. All of the other results are discarded. Empty value will return all Scan results.', }, { displayName: 'Key Condition Expression', @@ -912,7 +911,7 @@ export const itemFields: INodeProperties[] = [ name: 'projectionExpression', type: 'string', default: '', - description: 'Text that identifies one or more attributes to retrieve from the table. These attributes can include scalars, sets, or elements of a JSON document. The attributes in the expression must be separated by commas', + description: 'Text that identifies one or more attributes to retrieve from the table. These attributes can include scalars, sets, or elements of a JSON document. The attributes in the expression must be separated by commas.', }, { displayName: 'Filter Expression',