I'm trying to run locally a node lambda to debug it. I am using Serverless and this launch config in vsCode
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceRoot}/node_modules/.bin/sls",
"args": [
"invoke",
"local",
"--function",
"hello",
"--data",
"hello world"
]
}
]
}
My export.handler looks like this:
module.exports.handler = (event, context, callback) => {
if (event.triggerSource === CONSTANTS.TRIGGER_SOURCE) {
console.log("event = " + JSON.stringify(event));
const uri = process.env.SCT_URL_BASE;
const country = process.env.SCT_COUNTRY;
const username =
event.request.userAttributes[CONSTANTS.USER_ATTRIBUTES];
const codeP = event.request.codeParameter;
console.log("URI = " + url);
console.log("Code:" + codeP);
getUrlData(uri, country, username, codeP);
} else {
context.done(null, event);
}
};
When I run de debug mode it does nothing. Serverless does not throw any error, I just can not reach inside the function.
Also, there is another thing I can not understand. In serverless documentation it said:
--function or -f The name of the function in your service that you want to invoke locally. Required.
I don't know what they are refering in this, if a function that we call to run the lambda or the function that it is called when the lambda is called. In this case, the function that I am exporting is "handler" but it doesn't work either.
Thanks in advance.
I have used this approach and it works for me:
https://standardofnorms.wordpress.com/2017/12/03/locally-debugging-aws-lambdas-written-in-node-js/
The bad thing is that I would like to use serverless and not lambda-local package due to the greater community of serverless. Lambda-local works like charm though, so I send a big hug to its creator from here.
Answers to the first question are still very welcome.
EDIT: Ok, I figured this out.
Results that Serverless, as framework, uses a serverless.yml file when we need to add some configuration. There, I had to create the function I am going to run with the serverless command and then point it to the file where I have my handler. This is my serverles.yml right now:
service: serverless-simple
frameworkVersion: ">=1.1.0 <2.0.0"
provider:
name: aws
runtime: nodejs4.3
functions:
lambdaHandler:
handler: src/customMessageLambda.handler
events:
- http:
path: ping
Sure I have to research a little more on this file but I have solved my issue.
Hope this helps someone, sometime.
Related
I'm attempting to follow the NFT tutorial here. I have set up the accounts on Alchemy and Metamask created the .sol file. I have a .env file in root that looks like this:
API_URL = "https://eth-ropsten.alchemyapi.io/v2/your-api-key"
PRIVATE_KEY = "your-metamask-private-key"
My hardhat config file looks like this:
/**
* #type import('hardhat/config').HardhatUserConfig
*/
require('dotenv').config();
require("#nomiclabs/hardhat-ethers");
const { API_URL, PRIVATE_KEY } = process.env;
module.exports = {
solidity: {
compilers: [
{
version: "0.5.7"
},
{
version: "0.8.0"
},
{
version: "0.6.12"
}
]
},
defaultNetwork: "ropsten",
networks: {
hardhat: {},
ropsten: {
url: API_KEY,
accounts: [`0x${PRIVATE_KEY}`]
}
},
}
However when I try to compile I keep getting this error:
Invalid value
{"url":"https://eth-ropsten.alchemyapi.io/v2/your-api-key","accounts":["0xyour-metamask-private-key"]}
for HardhatConfig.networks.ropsten - Expected a value of type
HttpNetworkConfig.
I cannot seem to figure out why this is not a valid value for HttpNetworkConfig. What I have where url is a string and accounts is an array would appear to comply with what is in the documentation for network configs. It's a compile error so it would seem it cannot be a problem with the actual url or private key, but maybe I'm wrong about that. I willingly admit to being a noob here with only a cursory understanding of hardhat, solidity, and even js, etc. Any help appreciated.
Turns out, the problem was with my private key. Check carefully.
You are probably working at localhost:8545.
I think the issue is the value of the assets and some accounts used in your context exist on the mainnet.
To solve this problem, you need to hardfork the mainnet to your local.
Please check this guide.
https://hardhat.org/hardhat-network/guides/mainnet-forking.html
I was not setting my privateKey to the accounts element.
Turns out I was missing a value for my LIVE_PRIVATE_KEY as I also had a DEV_PRIVATE_KEY
I have 2 files:
controller.js
model.js
I'm making an express.js app.
So, model.js is required inside controller.js but I have this error when I call my api
And the logs are:
But here is the problem, './model.js' really does exist, but vercel doesn't recognize it
And works fine in local development and it is required correctly
this is model.js
const { nanoid } = require("nanoid");
const getDateStr = () => {
const now = new Date();
return `${now.getFullYear()}-${now.getMonth()+1}-${now.getDate()}`;
}
const Purchase = ({ id_user_buyer, id_user_seller, id_product, quantity }) => (
{
id_user_buyer,
id_user_seller,
id_product,
quantity,
id_purchase: nanoid(),
date: getDateStr(),
}
);
module.exports = {
Purchase
}
And this is controller.js
const err = require("../../../utils/error");
const { Purchase } = require("./model")
// others modules and they are well imported, so the problem is './model'
const userController = require("../user");
const productController = require("../product");
const cartController = require("../cart");
const TABLE = 'purchase';
function purchaseController(injectedStore) {
// example code
async function makePurchase(data) {
const purchase = Purchase(data);
await injectedStore.insert(TABLE, purchase);
}
return {
makePurchase,
}
}
module.exports = purchaseController;
As you can see, model.js is well imported inside controller.js I don't know why vercel says ERROR Cannot find module './model' I say it again, works fine in local development but not in vercel
A quick fix is copy and paste all the code of model.js inside controller.js I tried it, I deploy him and it worked.
All my app also works fine if I just comment that line where I import ./model , but obviously my application would stop having that functionality, so the first solution is uggly but works, but those are not the best solutions. the best solution is for the file to be imported correctly
Curious fact I tried renaming the file and it didn't help either. It also doesn't work if I import a new file.
NOTE I changed the nodejs version from 12 to 14, will that have something to do with it?
just in case I put my folder structure
root
api
this is my vercel.json
{
"version": 2,
"builds": [
{
"src": "/api/index.js",
"use": "#vercel/node"
}
],
"routes": [
{
"src": "/api/auth(.*)",
"dest": "/api/index.js"
},
{
"src": "/api/users(.*)",
"dest": "/api/index.js"
},
{
"src": "/api/products(.*)",
"dest": "/api/index.js"
},
{
"src": "/api/cart(.*)",
"dest": "/api/index.js"
},
{
"src": "/api/purchases(.*)",
"dest": "/api/index.js"
},
{
"src": "/api/sales(.*)",
"dest": "/api/index.js"
}
]
}
I don't know if it's a vercel bug or it's a mistake on my part. My application works currently but doing the trick that I named before, which was about putting all the code of model.js inside of controller.js
Thanks for reading the whole issue.
Well, I don't know why, but i think was a vercel bug, the solution for my problem was not to use optional chaining.
In controller.js I have more code and I was using optional chaining, just change the logic and works fine. Vercel supports optional chaining but with node 14.x and I was using node 12.x in vercel, so I change it to 14.x and works fine in others files, but not in controller.js
So, if you are using javascript new things, like optional chaining, nullish operator, etc. And you are using version 12.x in vercel, that will produce errors. So you change to node 14.x, it could give you bugs too.
So the best you can do is make sure from the beginning that you have version 14.x of node.js in vercel
how to change node version in vercel
Given the first code snippet. It leverages the Jest framework and Supertest lib. It gets currently generated via a GUI where the user makes some selections enters some addition data and exports the JavaScript file. Testing endpoints is the only scope of the generation (hence the combination of Jest and Supertest).
Editing an exported file happens only via an external editor like VSCode. Now the request came in to be able to edit the JavaScript via both the GUI and editor like VSCode.
So the idea is to create an intermediate e.g. "descriptive" JSON file, like the second snippet below, that can be modified within both an editor and by the GUI. After that, it gets transformed into the final JavaScript code.
Are there other methods that would accomplish the same effect? Since an intermediate file requires "learning" a new syntax an structure.
Is there a library that provides such functionality?
Is this a known concept and if so what is it called?
const app = require('./server');
const supertest = require('supertest');
const request = supertest(app);
describe('api tests', () => {
it('gets the test endpoint', async done => {
const response = await request.get('/test');
expect(response.status).toBe(200);
expect(response.body).toBe('hello world');
done()
});
});
{
"descibe": {
"description": "api tests",
"it": {
"description": "gets the test endpoint",
"request": {
"method": "get",
"url": "/test",
"expect": [
{
"response.status": "toBe(200)"
},
{
"response.body": "toBe('hello world')"
}
]
}
}
}
}
Node.js Alexa Task Issue
I'm currently coding a Node.js Alexa Task via AWS Lambda, and I have been trying to code a function that receives information from the OpenWeather API and parses it into a variable called weather. The relevant code is as follows:
var request = require('request');
var weather = "";
function isBadWeather(location) {
var endpoint = "http://api.openweathermap.org/data/2.5/weather?q=" + location + "&APPID=205283d9c9211b776d3580d5de5d6338";
var body = "";
request(endpoint, function (error, response, body) {
if (!error && response.statusCode == 200) {
body = JSON.parse(body);
weather = body.weather[0].id;
}
});
}
function testWeather()
{
setTimeout(function() {
if (weather >= 200 && weather < 800)
weather = true;
else
weather = false;
console.log(weather);
generateResponse(buildSpeechletResponse(weather, true), {});
}, 500);
}
I ran this snippet countless times in Cloud9 and other IDEs, and it seems to be working flawlessly. However, when I zip it into a package and upload it to AWS Lambda, I get the following error:
{
"errorMessage": "Cannot find module '/var/task/index'",
"errorType": "Error",
"stackTrace": [
"Function.Module._load (module.js:276:25)",
"Module.require (module.js:353:17)",
"require (internal/module.js:12:17)"
]
}
I installed module-js, request, and many other Node modules that should make this code run, but nothing seems to fix this issue. Here is my directory, just in case:
- planyr.zip
- index.js
- node_modules
- package.json
Does anyone know what the issue could be?
Fixed it! My issue was that I tried to zip the file using my Mac's built-in compression function in Finder.
If you're a Mac user, like me, you should run the following script in terminal when you are in the root directory of your project (folder containing your index.js, node_modules, etc. files).
zip -r ../yourfilename.zip *
For Windows:
Compress-Archive -LiteralPath node_modules, index.js -DestinationPath yourfilename.zip
Update to the accepted answer: When this error occurs, it means your zip file is not in the valid form which AWS requires.
If you double click on zip you will find your folder inside that your code file,but lambda wants that when you double click on zip it shoud show direct code files.
To achieve this:
open terminal
cd your-lambda-folder
zip -r index.zip *
Then, upload index.zip to AWS Lambda.
Check that file name and handler name are same:
That means that zip file has bundle.js file that exports handler function:
exports.handler = (event, context, callback) => {//...}
In my case it was because I had the handler file in inner src directory.
I had to change the 'Handler' property within Lambda from:
index.handler
to
src/index.handler
This is probably a permissions issue with files inside your deployment zip.
Try chmod 777 your files before packaging them in a zip file.
In my case the archive contained a folder "src" with index.js file, so I had to put to the handler: "src/index.handler"
In my case I had to replace
exports.handler = function eventHandler (event, context) {
with
exports.handler = function (event, context, callback) {
I got this error when I was using lambci/lambda:nodejs8.10 in windows.
I'd tried all of the solution listed above but none of which could help me deal with my issue(even though the error stack look the same as the question).
Here is my simple solution:
using --entrypoint flag to run a container to find out if the file is mounted into the container. It turns out I may got the share drive issue with my Docker Desktop.
I switched my docker daemon that day before, but everything works fine except this problem.
Anyway, remount my drive to Docker Desktop, you can both use the docker command or just open the Docker Desktop setting to apply.
In my case this was caused by Node running out of memory. I fixed that by adding --memory-size 1500 to my aws lambda create-function ... command.
As my title explains I am getting the following error:
{
"errorMessage": "Cannot find module 'index'",
"errorType": "Error",
"stackTrace": [
"Function.Module._resolveFilename (module.js:338:15)",
"Function.Module._load (module.js:280:25)",
"Module.require (module.js:364:17)",
"require (module.js:380:17)"
]
}
I have tried both solutions provided in creating-a-lambda-function-in-aws-from-zip-file and simple-node-js-example-in-aws-lambda
My config currently looks like:
and my file structure is:
and my index.js handler function looks like :
exports.handler = function(event, context) {
What else could be causing this issue aside from what was stated in those two answers above? I have tried both solutions and I have also allocated more memory to the function just incase thats why it couldn't run.
EDIT -
For the sake of trying, I created an even simpler version of my original code and it looked like this:
var Q = require('q');
var AWS = require('aws-sdk');
var validate = require('lambduh-validate');
var Lambda = new AWS.Lambda();
var S3 = new AWS.S3();
theHandler = function (event, context) {
console.log =('nothing');
}
exports.handler = theHandler();
And yet still does not work with the same error?
Try zipping and uploading the contents of the folder lambda-create-timelapse. Not the folder itself.
If this was unclear for anyone else, here are the steps:
Step 1
Navigate to the folder of your project, and open that folder so that you are inside the folder:
Step 2
Select all of the images you want to upload into to Lambda:
Step 3
Right-click and compress the files you have selected:
This will give you a .zip file, which is the file you need to upload to Lambda:
There are a lot of ways to automate this, but this is the manual procedure.
I ran into this problem a few times myself, and this indeed has to do with zipping the folder instead of just the contents like you're supposed to.
For those working from the terminal...
While INSIDE of the directory where the .js files are sitting, run the following:
zip -r ../zipname.zip *
The * is instructing the client to zip all the contents within this folder, ../zipname.zip is telling it to name the file zipname.zip and place it right outside of this current directory.
I had the same problem sometime ago - I reformatted the code.
function lambdafunc1(event, context) {
...
...
...
}
exports.handler = lambdafunc1
The problem occurs when the handler cannot be located in the zip at first level. So anytime you see such error make sure that the file is at the first level in the exploded folder.
To fix this zip the files and not the folder that has the files.
Correct Lambda function declaration can look like this:
var func = function(event, context) {
...
};
exports.handler = func;
You may have other syntax errors that prevent the index.js file from being properly ran. Try running your code locally using another file and using the index.js as your own module.
make sure in your handler following code added
exports.handler = (event, context, callback) => {
...
}
Another reason this can occur is if you don't do an npm install in the folder before packaging and deploying.