async getTaskExecutions()

in source/services/tasks/tasks.ts [504:561]


    async getTaskExecutions(taskId: string, sortType?: string, itemsPerPage?: number, lastKey?: object): Promise<DocumentClient.QueryOutput | ErrorReturn> {
        /**
         * DynamoDB has a bug to return LastEvaluatedKey even though there is no more data when the limit equals to the number of returned items.
         * For example, if the limit is 3, and the number of returned items is 3 but there is no more actual data to query, DynamoDB returns LastEvaluatedKey.
         * To resolve the bug, it will add 1 to the limit, and return the items after removing the last item. LastEvaluatedKey would be the new last item of the items.
         */
        if (!COMMON_UTIL.isStringValuesValid([taskId])) {
            return Promise.reject(
                COMMON_UTIL.getErrorObject('GetTaskExecutionsFailure', 400, 'Task ID cannot be empty.')
            );
        }

        // Default items per page is 10.
        if (!/^[1-9]\d*$/.test(`${itemsPerPage}`)) {
            itemsPerPage = 10;
        }

        let params: DocumentClient.QueryInput = {
            TableName: this.taskExecutionsTable,
            IndexName: 'taskId-startTime-index',
            ScanIndexForward: sortType === SortType.asc,
            KeyConditionExpression: 'taskId = :taskId',
            ExpressionAttributeValues: {
                ':taskId': taskId
            },
            Limit: itemsPerPage + 1 // plus 1 on purpose
        };

        if (lastKey && !COMMON_UTIL.isObjectEmpty(lastKey)) {
            params['ExclusiveStartKey'] = lastKey;
        }

        try {
            let result = await this.documentClient.query(params).promise();
            let items = result.Items;
            let lastEvaluatedKey = result.LastEvaluatedKey;
            if (items.length === itemsPerPage + 1) {
                // This means there should be more items to query with the actual limit (itemsPerPage).
                let item = items[itemsPerPage - 1];
                for (let key in result.LastEvaluatedKey) {
                    lastEvaluatedKey[key] = item[key];
                }

                // To return itemsPerPage, pop the end of the result.
                items.pop();
            }

            return Promise.resolve({
                Items: items,
                LastEvaluatedKey: lastEvaluatedKey
            });
        } catch (error) {
            LOGGER.error(`getTaskExecutions Error: ${JSON.stringify(error)}`);
            return Promise.reject(
                COMMON_UTIL.getErrorObject('GetTaskExecutionsFailure', 500, 'Error occurred while getting task executions.', error)
            );
        }
    }