AWS AmplifyAUTH: flutter: [ERROR]: CreateAuthChallenge failed with error SyntaxError: await is only valid in async function - node.js

Getting the captioned error message onTap signUpButton() within AuthenticatorForm(). Seems like a very idiomatic error message, but can't seem to find what's wrong.
Here is my createAuthChallenge.js
const AWS = require('aws-sdk');
const digitGenerator = require('crypto-secure-random-digit');
function sendSMS(phone, code) {
const params = {
Message: code,
PhoneNumber: phone,
};
return new AWS.SNS({apiVersion: '2010-03-31'}).publish(params).promise();
}
async function createAuthChallenge(event) {
if (event.request.challengeName === 'CUSTOM_CHALLENGE') {
const randomDigits = digitGenerator.randomDigits(6).join('');
const challengeCode = String(randomDigits).join('');
await sendSMS(event.request.userAttributes.phone_number, challengeCode);
event.response.privateChallengeParameters = {};
event.response.privateChallengeParameters.answer = challengeCode;
}
}
exports.handler = async (event) => {
createAuthChallenge(event);
};
And my package.json for the same
{
"name": "XYZ",
"version": "2.0.0",
"description": "Lambda function generated by Amplify",
"main": "index.js",
"license": "Apache-2.0",
"devDependencies": {
"#types/aws-lambda": "^8.10.92"
},
"dependencies": {
"crypto-secure-random-digit": "^1.0.9"
}
}
I can't seem to find the right solution for this, can anyone help please?

Please try to replace your last line with:
exports.handler = createAuthChallenge;
If it doesn't work, can you add some other details?

Not really a useful answer, but as self-resolved.
Ultimately just used the same codes that I copied above, but redid everything from amplify delete > amplify init > amplify add auth > amplify push.
After this, no errors in simulator.
If anyone runs into similar problems, the best approach based off my experience on this, is to check the cloudwatch logs of the lambdas fired. In most cases, the logs should do a better job of pointing out where the issue is than the error messages in local. If that doesn't work, backup everything and reset amplify.

Related

Prisma seed - cannot read properties of undefined (reading 'findFirst')

I have a weird issue using prisma seed that I've never faced before and struggling to understand what causes it. The app is hosted in a nextjs full-stack project.
I have the following prisma init script:
const prisma = new PrismaClient();
export default prisma;
When using prisma in my app (next dev), everything works and the queries are being executed.
When I try to run the seed script however, it fails with TypeError: Cannot read properties of undefined (reading 'findFirst')
Here is the seed script:
async function main() {
const existingUser = await db.user.findFirst();
// ...not relevant
}
main()
.then(async () => await db.$disconnect())
.catch(async e => {
console.error(e);
await db.$disconnect();
process.exit(1);
});
package.json prisma section:
"prisma": {
"seed": "ts-node src/server/db/seed.ts",
"schema": "src/server/db/schema.prisma"
},
tsconfig.json ts-node section:
"ts-node": {
"require": ["tsconfig-paths/register"],
"transpileOnly": true,
"compilerOptions": {
"module": "commonjs"
}
},
Printing the prisma client on the seed script returns {}, instead of the actual instance that I can see while printing in dev mode.
Any ideas are welcome, thanks!
A few debugging hours later, I finally found the issue. This code fragment is located in the prisma runtime config:
const dmmfModelKeys = Object.keys(client._baseDmmf.modelMap);
const jsModelKeys = dmmfModelKeys.map(dmmfToJSModelName);
const allKeys = [...new Set(dmmfModelKeys.concat(jsModelKeys))];
I have seen that while the first 2 variables were outputting a result, creating a new Set was actually returning an empty array, instead of the real value.
By default, NextJS uses es5 as a target in tsconfig. ES5 however does not yet have the Set construct, which was causing the problem.
Upgrading to es2015 solved the problem.
I was just expecting some kind of an error, instead of silent fail..

Netlify functions not found on dev server

I have followed several blogs and questions related to the same problem I am having. It is exactly like this question. However, I am still having issues.
So, I am running netlify dev and trying to access my netlify functions. I have a function in /netlify/functions/ping. The function works as intended when I access the randomized port for the netlify functions (something like localhost:55832...).
However, using the localhost:8888/.netlify/functions/ping gives me a 404 error.
Here is my /netlify/functions/ping file:
import { Handler } from '#netlify/functions';
const handler: Handler = async (event, context) => {
return {
statusCode: 200,
body: JSON.stringify({ data: "pong" }),
};
};
export { handler };
here is where I am trying to call my function on a page
export default function HomePage() {
useEffect(() => {
async function pingpong() {
const res = await fetch(`/.netlify/functions/ping`);
console.log(res);
}
pingpong();
}, []);
return (
...
I have also tried to alter my netlify.toml with the following
[[redirects]]
from = "/api/*"
to = "/.netlify/functions/:splat"
status = 200
force = true
what's start script you use in package.json?
Keep in mind that, to enable Netlify Functions you have to use netlify-cli, i.e. ntl command to run on local dev server.
No more specific configuration, just follow docs, and use that simple netlify/functions/hello.js example.
Then run using ntl dev, you function will be avaiable on /.netlify/functions/hello. easy.

How to use Error.captureStackTrace in node.js

Lately I'm going through the implementation of Global Error Handling Middleware in node.js.
Then, I came across this Error.captureStackTrace(this,this.constructor).
I have checked the Node documentation & found that - Creates a .stack property on targetObject, which when accessed returns a string representing the location in the code at which Error.captureStackTrace() was called.
MDN Docs - Maintains proper stack trace for where our error was thrown
appError.js File
class AppError extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
// Error.captureStackTrace(this, this.constructor);
}}
app.js File
const AppError = require('./appError');
const express = require('express');
const app = express();
app.all('*', (req,res,next) => {
const custErr = new AppError('Mentioned Route is not available on server','404');
next();
})
My Observations when I tried to debug the code:
I found that .stack property is available on the custErr object even though I have commented the
Error.captureStackTrace(this, this.constructor) in appError.js file.
I'm still confused how to leverage the Error.captureStackTrace()
Can someone explain me on this?
One thing you need to understand is that apart from instances of the Error-classs the throw-statement can also throw other types. Consider this for example:
function throwSomeObj() {
throw {statusCode: 500};
}
try {
throwSomeObj();
} catch(err) {
console.log(err);
console.log(err.stack);
}
The exception that is thrown yields the object you passed to it, i.e. {statusCode: 500}. Now, as you can see this object does not have any stack-trace, since undefined is logged.
However, you can use Error.captureStackTrace to capture the stack-trace where you throw the error. Consider this:
function throwObjWithStacktrace() {
const someError = {statusCode: 500}
Error.captureStackTrace(someError)
throw someError;
}
try {
throwObjWithStacktrace();
} catch (err) {
console.log(err);
console.log(err.stack);
}
As you can see, now err contains the stack property and contains the stack to the function where the error was thrown.
Note that when instantiating a new Error-object the stack will automatically be set on that object.
So Today I got this error so what you have to do is follow these steps.
first of all, kill your ports by using npx kill-port 8000
see this
check you have installed all the dependencies.(reinstall them)
In my case I have reinstalled all the dependencies.
and if the error still persists, reinstall the node.
see this now after following all the steps
You can add this to your package.json file.
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon --experimental-modules --es-module-specifier-resolution=node index.js"
},
In my case, I had set the wrong path, so the node did not find the right path and what I did was:
Moved my src folder into my server folder.
Executed node again: node src/server.mjs
Done, server up and running.

Mocha testing path argument in package.json

Note: I'm a complete noob to nodejs. Please explain your answer in such a way somebody who has experience in other programming languages, but creates his very first nodejs application can understand =).
I'm trying to write a simple test application which should automate testing an external service against an OpenApi 3.0 specification.
I've pulled together some example code in order to attempt to automate testing the OpenApi spec against an external service which implements the API using mocha and chai.
My problem seems now that my mocha test modules cannot be found.
I get the following error message:
> client_test#1.0.0 test /Users/user1/dev/app/app-rt/client_test
> mocha ./test/**/*.test.js
/Users/user1/dev/app/app-rt/client_test/node_modules/yargs/yargs.js:1163
else throw err
^
Error: The "path" argument must be an absolute filepath
My package.json:
{
"name": "client_test",
"version": "1.0.0",
"description": "Client Tester",
"main": "index.js",
"scripts": {
"test": "mocha ./test/**/*.test.js"
},
"license": "UNLICENSED",
"dependencies": {
"chai-http": "^4.3.0",
"chai-openapi-response-validator": "^0.2.4",
"mocha": "^6.2.0",
"nock": "^11.3.2"
}
}
The little test application in test/client_all.test.js:
// Set up Chai
const chai = require('chai');
const expect = chai.expect;
// Import this plugin
const chaiResponseValidator = require('chai-openapi-response-validator');
const baseUrl = 'http://localhost:8081';
// Load an OpenAPI file (YAML or JSON) into this plugin
chai.use(chaiResponseValidator('./spec/app.json'));
// Get an HTTP response using chai-http
chai.use(require('chai-http'));
// Write your test (e.g. using Mocha)
describe('GET /zones', function() {
it('should satisfy OpenAPI spec', async function() {
const res = chai.request(baseUrl).get('/zones');
expect(res.status).to.equal(200);
// Assert that the HTTP response satisfies the OpenAPI spec
expect(res).to.satisfyApiSpec;
});
});
Can you help me figure out why the paths cannot resolved, and how to fix it? Feel free to comment on the test code as well, if you think I'm doing it wrong.
The problem is with the package chai-openapi-response-validator. Try something like this:
// Import this plugin
const chaiResponseValidator = require('chai-openapi-response-validator');
const baseUrl = 'http://localhost:8081';
// New code
const path = require('path')
const specPath = path.resolve('./spec/app.json')
// Load an OpenAPI file (YAML or JSON) into this plugin
chai.use(chaiResponseValidator(specPath));
Make sure the path to the app.json file is relative to the package.json file, or use another method to convert it to an absolute path.

Error:"Failed to get the current sub/segment from the context" when use AWS X-ray in Lambda with node.js

I am trying to use implement the AWS X-ray into my current project (using Node.js and Serverless framework). I am trying to wire the X-ray to one of my lambda function, I got the problem of
Error: Failed to get the current sub/segment from the context.
at Object.contextMissingRuntimeError [as contextMissing] (/.../node_modules/aws-xray-sdk-core/lib/context_utils.js:21:15)
at Object.getSegment (/.../node_modules/aws-xray-sdk-core/lib/context_utils.js:92:45)
at Object.resolveSegment (/.../node_modules/aws-xray-sdk-core/lib/context_utils.js:73:19).....
code below:
import { DynamoDB } from "aws-sdk";
import AWSXRay from 'aws-xray-sdk';
export const handler = async (event, context, callback) => {
const dynamo = new DynamoDB.DocumentClient({
service: new DynamoDB({ region })
});
AWSXRay.captureAWSClient(dynamo.service);
try {
// call dynamoDB function
} catch(err) {
//...
}
}
for this problem, I use the solution from
https://forums.aws.amazon.com/thread.jspa?messageID=821510&#821510
the other solution I tried is from https://forums.aws.amazon.com/thread.jspa?messageID=829923&#829923
code is like
import AWSXRay from 'aws-xray-sdk';
const AWS = AWSXRay.captureAWS(require('aws-sdk'));
export const handler = async (event, context, callback) => {
const dynamo = new AWS.DynamoDB.DocumentClient({region});
//....
}
Still not working...
Appreciated to the help of any kind.
As you mention, that happened because you're running locally (using serverless-offline plugin) and the serverless-offline plugin doesn't provide a valid XRAY context.
One possible way to pass this error and still be able to call your function locally is setting AWS_XRAY_CONTEXT_MISSING environment variable to LOG_ERROR instead of RUNTIME_ERROR (default).
Something like:
serverless invoke local -f functionName -e AWS_XRAY_CONTEXT_MISSING=LOG_ERROR
I didn't test this using serverless framework but it worked when the same error occurred calling an amplify function locally:
amplify function invoke <function-name>
I encountered this error also. To fix it, I disabled XRay when running locally. XRay isn't needed when running locally because I can just set up debug log statements at that time.
This is what the code would look like
let AWS = require('aws-sdk');
if (!process.env.IS_OFFLINE) {
const AWSXRay = require('aws-xray-sdk');
AWS = AWSXRay.captureAWS(require('aws-sdk'));
}
If you don't like this approach, you can set up a contextStrategy to not error out when the context is missing.
Link here
AWSXRay.setContextMissingStrategy("LOG_ERROR");
If you don't want the error clogging up your output you can add a helper that ignores only that error.
// Removes noisy Error: Failed to get the current sub/segment from the context due to Xray
export async function disableXrayError() {
console.error = jest.fn((err) => {
if (err.message.includes("Failed to get the current sub/segment from the context")) {
return;
} else {
console.error(err);
}
});
}

Resources