An error occurred during the execution of the AWS S3 selectObjectContent and DynamoDB putItem functions, resulting in a runtime error of "TypeError: Cannot read property 'Payload' of undefined."

Hey there! I'm currently working on a TypeScript async function in an AWS Lambda environment to process data stored in S3 using `s3.selectObjectContent`. The goal is to extract certain values and then write them into a DynamoDB table using `dynamoDb.putItem`. However, I encountered an error where the S3 payload data variable is reported as undefined before the s3 command completes. Despite this error, the function still manages to write to the database table asynchronously. Could you provide any insights on how I can improve this code or suggest potential fixes?

export class Handler {
    import { S3, DynamoDB } from 'aws-sdk'
    import { DID_TABLENAME, IP_DEVICE_HISTORY_TABLENAME } from './Constants'
      dynamodb = new DynamoDB()
      s3 = new S3()

      async handle(event: SQSEvent): Promise<void> {
       console.log('Entering handler')
       console.log(event)
       this.srcBucket = 'my-bucket'
       this.srcKey = 'myfile.gzip'
       await this.prepareAndQuery()
     }
      private async prepareAndQuery(): Promise<any> {
             console.log('Preparing params')
             const params = {
             Bucket: this.srcBucket,
             Key: this.srcKey,
             ExpressionType: 'SQL',
             Expression: 'SELECT * FROM s3object',
             InputSerialization: { CompressionType: 'GZIP', JSON: { Type: 'LINES' }},
             OutputSerialization: { JSON: { RecordDelimiter: ' ' }}}
             console.log('Sending s3 command')
             try {
               this.s3selectOutput = await this.s3.selectObjectContent(params).promise()
               const events: any = this.s3selectOutput.Payload
               for await (const event of events) {
                 try {
                       if(event.Records) {
                       // THIS LINE BELOW IS THE POINT OF FAILURE 
                       const s3selectOutput: any = event.Records.Payload.toString()
                       const decoded = decodeURIComponent(s3selectOutput.replace(/\+|\t/g, ' '))
                       const jsoncontent = JSON.parse(decoded)
                       const udid = jsoncontent.pyAppResponse.logs.udid_logs.udid;
                       const did = jsoncontent.pyAppResponse.logs.udid_logs.did;
                       if ((did !== null) && (udid !== null)) {
                          events.pause()
                          const paramsdiddB = {
                          Item: {
                          'did': { S: did },
                          'udid': { S: udid }},
                          ReturnConsumedCapacity: 'TOTAL',
                          TableName: DID_TABLENAME }
                          console.log(`going to write to dbs ${DID_TABLENAME}`)
                          const _retValue = await this.dynamodb.putItem(paramsdiddB).promise().then((_dBdata: any) => {
                            console.log(`Successfuly wrote to tables: ${DID_TABLENAME}`)
                              }).catch((dBerr: any) => {
                                console.log('Error writing to database tables')
                                console.log(dBerr.stack)
                              })
                              events.resume()
                            }
                          }
                        }
                        catch (s3undefinederr) {
                          if (s3undefinederr instanceof TypeError) {
                            console.log(s3undefinederr)
                            throw s3undefinederr
                          }
                        }
                        if (event.End !== null) {
                          console.log('SelectObjectContent completed')
                        }
                      }
                    }
                    catch (s3error) {
                      console.log(s3error)
                      throw s3error
                    }
                    return this.s3selectOutput
                  }
   }

Error Message at Runtime (even though it completes the job!

    at Handler.<anonymous> (/var/task/build/dist/Handler.js:144:66)
    at Generator.next (<anonymous>)
    at fulfilled (/var/task/build/dist/Handler.js:5:58)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
2020-09-30T04:58:57.312Z    9783b6c9-d88e-4b14-82d0-607bd14ec730    ERROR   Invoke Error    {"errorType":"TypeError","errorMessage":"Cannot read property 'Payload' of undefined","stack":["TypeError: Cannot read property 'Payload' of undefined","    at Handler.<anonymous> (/var/task/build/dist/Handler.js:144:66)","    at Generator.next (<anonymous>)","    at fulfilled (/var/task/build/dist/Handler.js:5:58)","    at processTicksAndRejections (internal/process/task_queues.js:97:5)"]}

Answer №1

To resolve the issue, I successfully resolved it by implementing a try + catch statement to handle the error. Here is how I did it:

catch (s3undefinederr) {
 console.log(s3undefinederr)
 if (s3undefinederr instanceof Error) {
   throw s3undefinederr
 }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Enhance your coding experience with TypeScript's autocomplete in Visual Studio Code

After migrating a project from JavaScript to TypeScript, I am not seeing autocomplete suggestions or type hints when hovering over variables in Visual Studio Code editor (Version 1.7.2). Even the basic example provided below does not display any auto-com ...

One way to consolidate multiple components in a single location without altering user-input data

I currently have 3 separate components, namely PersonalInfoComponent, EducationalInfoComponent, and ExperienceComponent. These components are all being displayed within the ResumeComponent. The issue I am facing is that when a user enters information in t ...

Simplifying the process of importing SCSS files in Angular 5

After extensive searching, I've come up empty-handed in finding a solution to my project dilemma. Let's say I have various .scss files within my project such as mixins.scss, vars.scss, and base.scss. Naturally, I would like to use these files in ...

Retrieving data values in Typescript

Within my code, I have the following lines placed inside an ngOnInit: this.state.params.subscribe( (params: any) => { console.log("These are the parameters: " + params['id']); if(params['id']){ consol ...

List containing a generic element

I am trying to define a type that consists of an array of pairs containing a constructor function and an argument that can be passed into the constructor. Additionally, I have the same question regarding rest function arguments. How can I achieve this? Fo ...

Having difficulty adjusting the configuration settings for an embedded report within Angular 7

While attempting to integrate a Power BI report with Angular 7, I encountered an unexpected error when trying to configure the settings of the report. The error message stated: Type '{ filterPaneEnabled: boolean; navContentPaneEnabled: boolean; }&apos ...

Typescript - Guarantee Presence of Generic Property on Generic Type Through Clear Error Message

(Heads up for Typescript beginners) I'm working on a reusable reducer function that takes a state and an action, but is designed to only accept state objects with a specific type at a particular key. This key is passed as a parameter to the function. ...

Converting JS carousel to TS for showcasing multiple items

I am currently working on integrating a bootstrap carousel into my Angular project and I need to convert my JavaScript file to a TypeScript file. As someone who is new to this, I'm unsure of the process for converting and implementing it in a .ts file ...

I have disabled the autoHideDuration feature for Material UI Snackbar

I am looking to create a dynamic Material UI Snackbar that can either automatically hide after a specified time or remain open indefinitely. This customization will be based on the props passed to my custom component. In regards to the autoHideDuration at ...

Automatically showcasing filtered arrays in the Angular view through efficient sorting mechanisms

I have successfully managed to post and retrieve data from a database. However, I am facing an issue where the view only updates the value upon refreshing. It seems like the filter method is creating a new array, so I am puzzled as to why it's not sho ...

How can I add two values in Angular?

Adding two values is not giving me the expected result. For instance, 1 + 1 = 2, but instead I am obtaining 11. This is my code: this.newpoint = this.data.point + 1; console.log(this.newpoint); The value of this.data.point is 0, but it might be in stri ...

Incorporating Ionic v3 with the latest StripeJS/Stripe Elements version 7.26.0

I have encountered two separate issues while trying to integrate the new version of Stripe into my Ionic v3 app. (Please refrain from suggesting an upgrade to Ionic v5, as it is currently not feasible for our team at this time!) Within my ionDidLoad funct ...

Creating a custom button for exporting a high chart to CSV

My Angular project involves exporting a chart to various formats, such as png, jpeg, pdf, and SVG. However, I am encountering an issue when trying to export the chart as CSV or . I have attempted the following code: this.lineChart.chart.downloadCSV(); //F ...

Retrieve the individuals within the delimiter

Looking for a solution to modify the characters within square brackets in a given string. For instance, I have a string that looks like "[A] [B] this is my [C] string". How can I update these bracketed characters by adding or removing brackets? ...

Handling errors in Nestjs HttpService using AxiosRequestConfig's validateStatus function

When working with HttpService in Nestjs to consume an external service, it is important to handle http errors status codes (such as 401, 500, etc). Below is my current implementation: import { Injectable } from '@nestjs/common'; import { HttpServ ...

What is the best way to prioritize the display of custom login buttons based on the last button used for login?

I have implemented 4 different login methods for my app, each with its own associated component. I am looking to rearrange the buttons based on the last used login method. I already have a function to determine the last login method. let lastSignedInMetho ...

After the build/export process, the NextJS routing fails to function properly when I manually insert the URL

While testing my application on localhost using npm run dev, everything works normally. I can access routes like localhost:3000/settings/account and they render correctly. However, after running npm run build and npm run export, testing with serve -s out a ...

Using Typescript with Vue to create a reactive exported variable

Scenerio Setup Currently, I have developed a Vue3 + Firebase project which includes an object called userInfo in the main.ts file. The export declaration is as follows: export var userInfo :any = {} It is important to note that the :any declaration is ...

Implementing a NextJS client component within a webpage

I am currently working with NextJS version 14 and I am in the process of creating a landing page. In one of the sections, I need to utilize the useState hook. I have specified my component as "use-client" but I am still encountering an error stating that " ...

The powerful combination of Vuetify, Inertia, and Typescript creates a

Currently, I am working with Vuetify and Inertia while using Typescript. I am faced with the challenge of passing shared data to the items prop of a vuetify AutoComplete component: <v-autocomplete :items="$page.props.countries"></v-auto ...