https://serverless-stack.com/ logo
#help
Title
# help
a

Adrian Schweizer

03/24/2022, 6:35 PM
has anyone had the problem that using await in an async sqs consumer results in an error:
Uncaught Exception 	{"errorType":"TypeError","errorMessage":"Cannot read property 'push' of undefined",
This is the full error message:
Copy code
Uncaught Exception 	{"errorType":"TypeError","errorMessage":"Cannot read property 'push' of undefined","code":"TypeError","message":"Cannot read property 'push' of undefined","time":"2022-03-24T18:44:22.378Z","stack":["TypeError: Cannot read property 'push' of undefined","    at Object.debug [as log] (/home/adsc/projects/convento/.build/src/participations/mailReminder.js:56:8)","    at Request.LOG_REQUEST (/home/adsc/projects/convento/node_modules/aws-sdk/lib/event_listeners.js:608:16)","    at Request.callListeners (/home/adsc/projects/convento/node_modules/aws-sdk/lib/sequential_executor.js:106:20)","    at Request.emit (/home/adsc/projects/convento/node_modules/aws-sdk/lib/sequential_executor.js:78:10)","    at Request.emit (/home/adsc/projects/convento/node_modules/aws-sdk/lib/request.js:686:14)","    at Request.transition (/home/adsc/projects/convento/node_modules/aws-sdk/lib/request.js:22:10)","    at AcceptorStateMachine.runTo (/home/adsc/projects/convento/node_modules/aws-sdk/lib/state_machine.js:14:12)","    at /home/adsc/projects/convento/node_modules/aws-sdk/lib/state_machine.js:26:10","    at Request.<anonymous> (/home/adsc/projects/convento/node_modules/aws-sdk/lib/request.js:38:9)","    at Request.<anonymous> (/home/adsc/projects/convento/node_modules/aws-sdk/lib/request.js:688:12)"]}
it seems something is trying to log the request...but what? And why only when I use await?
This is the consumer code:
Copy code
export async function consumer(event) {
   for (const record of event.Records) {
      console.log(record.body);
      const { mail, participation, event } = JSON.parse(record.body);
      //await sendMail(mail, participation, event);
      console.log("mail sent");
      // await dynamodb.update({
      //    TableName: process.env.TABLE_NAME_PARTICIPATIONS,
      //    Key: {
      //       participationId: participation.participationId,
      //    },
      //    UpdateExpression: "SET reminderSent = :reminderSent",
      //    ExpressionAttributeValues: {
      //       ":reminderSent": true,
      //    },
      //    ReturnValues: "ALL_NEW",
      // });
      console.log("dynamodb updated");
   }

   return {};
}
Like this, it works, everything is printed fine, the vars are properly destructured, all debug output is shown, but as soon as I comment one of the blocks in, the error happens and debug output stops above the block
what's REALLY weird, though, is that the dynamodb.update statement actually seems to run...but the error still happens, which means the message is not purged from the queue and it tries over and over again
it also doesn't seem to be await itself, because I tried an await sleep(1000) between the console.log statements, and those run fine without error
There must be something wrong with how sst.Queue consumers work, because my code now looks like this, and it still produces the error:
Copy code
export async function consumer(event) {
   const client = new AWS.DynamoDB.DocumentClient();

   for (const record of event.Records) {
      const { mail, participation, event } = JSON.parse(record.body);
      console.log(process.env.TABLE_NAME_PARTICIPATIONS);
      console.log(mail);
      console.log(participation.participationId);
      console.log(event.eventId);
      await client.update({
         TableName: process.env.TABLE_NAME_PARTICIPATIONS,
         Key: {
            participationId: participation.participationId,
         },
         UpdateExpression: "SET reminderSent = :reminderSent",
         ExpressionAttributeValues: {
            ":reminderSent": true,
         },
      }).promise();
      console.log("all done");
   }

   return {};
}
I'm gonna try to make a minimal case to verify this
fuck me it works in the minimal example
it must be some weird debug logging option I have turned on somewhere in AWS
so, i got it to work somewhat
the mail is sent, the db is updated
the reason the mail wasn't sent was because the consumer didn't have SES permissions
but the strange error from OP still pops up in the console
and it still prevents the SQS messages from being purged
if I set
AWS.config.logger = console;
the error doesn't occur
f

Frank

03/24/2022, 10:30 PM
hmm.. if you print out
console.log(AWS.config.logger)
, is it undefined before u set it to
console
?
a

Adrian Schweizer

03/24/2022, 10:40 PM
I'm almost certain it's a bug somewhere in the old aws libs i'm using....currently trying to reproduce it exactly in a new sst checkout
yeah, forget about the whole thing, it works fine in a new checkout
I'm gonna shuffle my project resources over to this new base tomorrow
but let me still try your suggestion, just for curiosity's sake
it's not undefined, it's
{ log: [Function: debug] }
anyway, let's forget about this issue. I have to update tailwind anyway, now is a good opportunity
but thanks for your suggestion
Damn, I still have the same problem, even after moving the whole project to an updated SST base. Still getting
"TypeError: Cannot read property 'push' of undefined","    at Object.debug [as log] (/home/adsc/projects/convento/.sst/artifacts/dev3-convento-cron-ReminderMailQueue-Consumer_ReminderMailQueue/src/participations/mailReminder.js:12106:8)
The code is now exactly as it has worked in a newly checked out SST project
so I guess it must be some config in AWS console or something? what the hell can it be?
t

thdxr

03/25/2022, 3:54 PM
well sst won't have too much of an effect on your application code
but can you try running with
NODE_OPTIONS=--enable-source-maps
might get a more useful stack trace
a

Adrian Schweizer

03/25/2022, 3:54 PM
the move to an updated SST base was done because yesterday I wrote a small minimal case in a new SST checkout, and that worked
ok, let me try that
my guess was that it was a bug in some aws libs...I was still on a base from almost a year ago, I think
@thdxr it's a queue consumer, do I have to set it in the ernvironment?
@thdxr thanks man, it seems it's some debug util from the sst tutorials that is interfering with it somehow
This is the new error message:
Copy code
Uncaught Exception 	{"errorType":"TypeError","errorMessage":"Cannot read property 'push' of undefined","code":"TypeError","message":"Cannot read property 'push' of undefined","time":"2022-03-25T16:02:11.904Z","stack":["/home/adsc/projects/convento/src/util/debug.js:10","   logs.push({","        ^","","TypeError: Cannot read property 'push' of undefined","    at Object.debug (/home/adsc/projects/convento/src/util/debug.js:10:9)","    at Request.LOG_REQUEST (/home/adsc/projects/convento/node_modules/aws-sdk/lib/event_listeners.js:608:16)","    at Request.callListeners (/home/adsc/projects/convento/node_modules/aws-sdk/lib/sequential_executor.js:106:20)","    at Request.emit (/home/adsc/projects/convento/node_modules/aws-sdk/lib/sequential_executor.js:78:10)","    at Request.emit (/home/adsc/projects/convento/node_modules/aws-sdk/lib/request.js:686:14)","    at Request.transition (/home/adsc/projects/convento/node_modules/aws-sdk/lib/request.js:22:10)","    at AcceptorStateMachine.runTo (/home/adsc/projects/convento/node_modules/aws-sdk/lib/state_machine.js:14:12)","    at /home/adsc/projects/convento/node_modules/aws-sdk/lib/state_machine.js:26:10","    at Request.<anonymous> (/home/adsc/projects/convento/node_modules/aws-sdk/lib/request.js:38:9)","    at Request.<anonymous> (/home/adsc/projects/convento/node_modules/aws-sdk/lib/request.js:688:12)"]}
and this is the code of said debug.js util:
Copy code
import util from "util";
import AWS from "aws-sdk";

let logs;

// Log AWS SDK calls
AWS.config.logger = { log: debug };

export default function debug() {
   logs.push({
      date: new Date(),
      string: util.format.apply(null, arguments),
   });
}

export function init(event) {
   logs = [];

   // Log API event
   debug("API event", {
      body: event.body,
      pathParameters: event.pathParameters,
      queryStringParameters: event.queryStringParameters,
   });
}

export function flush(e) {
   logs.forEach(({ date, string }) => console.debug(date, string));
   console.error(e);
}
I guess the problem is that this util is problematic for queue consumers
init is probably not called
ah, i see it now
it's because I have the consumer code in the same file as the code for the cronjob handler
the cronjob handler is importing this debug utility
so it's also doing the aws config logger thing for the consumer, but never calls init, because the consumer doesn't use the handler wrapper
jeez, this is one of those oddly specific problems that probably noone else on the planet is having
but thanks to your source maps hint I was able to solve it, thanks again @thdxr
my project is now also on a new SST + tailwind stack, so I guess the time was not all lost
t

thdxr

03/25/2022, 4:27 PM
haha glad you figured it out - are you saying somewhere in sst we tell you to use that util file?
it usually works great, because you wrap your lambdas into the handler defined below, but in my case, I was writing a consumer function that didn't use the handler, so init of that debug util was never called
@thdxr relating to the source maps parameters, is it advisable to turn that constantly on for local dev maybe? And if so, how?
f

Frank

03/25/2022, 6:29 PM
@Adrian Schweizer we noticed in some cases the source maps cause function to load up slower when running locally. Doesn’t happen all the time.
so if u are not experience any slowness, go for it
t

thdxr

03/25/2022, 8:27 PM
You can set it in package.json as part of the start script
or you can set it in stacks code using app.setDefaultFunctionProps
a

Adrian Schweizer

03/25/2022, 10:19 PM
really helpful, thanks @Frank and @thdxr
3 Views