Smart contract method is not a function in web3 - javascript

I am trying to follow an older tutorial on web3, but am getting errors that I believe are due Solidity being updated. I have the following code shown below
var express = require("express"),
Web3 = require("web3"),
web3;
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider);
} else {
// set the provider you want from Web3.providers
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}
web3.eth.defaultAccount = web3.eth.accounts[0];
//define contract variable using ABI from compiled Remix tab.
var myContract = new web3.eth.Contract([abi_data]);
myContract.options.address = 'contract_address';
myContract.methods.totalSupply(function(err,res){
if(!err){
console.log(res);
} else {
console.log(err);
}
})
where abi_data is my contract's abi data, contract_address is my contract's actual address in the Roptsen test network, and where totalSupply() is the method in my solidity smart contract on the Ropsten test network that returns the total supply of the token referenced in the contract. When testing this with node app.js to see if this logs properly, this error is returned...
/home/ubuntu/workspace/node_modules/web3-eth-contract/src/index.js:693
throw errors.InvalidNumberOfParams(args.length, this.method.inputs.length, this.method.name);
^
Error: Invalid number of parameters for "totalSupply". Got 1 expected 0!
at Object.InvalidNumberOfParams (/home/ubuntu/workspace/node_modules/web3-core-helpers/src/errors.js:32:16)
at Object._createTxObject (/home/ubuntu/workspace/node_modules/web3-eth-contract/src/index.js:693:22)
at Object.<anonymous> (/home/ubuntu/workspace/client/app.js:290:25)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:389:7)
at startup (bootstrap_node.js:149:9)
And totalSupply is defined in Soldiity as follows...
function totalSupply() constant returns (uint256 totalSupply){
return _totalSupply;
}
Using Adam's fix, I still get the following error...
Error: Invalid JSON RPC response: ""
at Object.InvalidResponse (/home/ubuntu/workspace/node_modules/web3-core-helpers/src/errors.js:42:16)
at XMLHttpRequest.request.onreadystatechange (/home/ubuntu/workspace/node_modules/web3-providers-http/src/index.js:73:32)
at XMLHttpRequestEventTarget.dispatchEvent (/home/ubuntu/workspace/node_modules/xhr2/lib/xhr2.js:64:18)
at XMLHttpRequest._setReadyState (/home/ubuntu/workspace/node_modules/xhr2/lib/xhr2.js:354:12)
at XMLHttpRequest._onHttpRequestError (/home/ubuntu/workspace/node_modules/xhr2/lib/xhr2.js:544:12)
at ClientRequest.<anonymous> (/home/ubuntu/workspace/node_modules/xhr2/lib/xhr2.js:414:24)
at emitOne (events.js:96:13)
at ClientRequest.emit (events.js:188:7)
at Socket.socketErrorListener (_http_client.js:310:9)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at emitErrorNT (net.js:1277:8)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickCallback (internal/process/next_tick.js:104:9)

Take a closer look at the web3 1.0 documentation for calling methods (it's very different from the 0.2x API). To call a contract method, you need to first create the method object using contractInstance.methods.methodName() replacing "methodName" with the method in the contract you want to call. You also need to pass in the parameters for the contract function to this method (the callback does not get passed in here). With the method object, you can then use either the call method (for constant functions) or send (for transactions). totalSupply should be a constant function, so your code should be:
myContract.methods.totalSupply().call(function(err,res){
if(!err){
console.log(res);
} else {
console.log(err);
}
);
Or you can use the returned Promise instead of passing in the callback:
myContract.methods.totalSupply().call().then(function(res){
console.log(res);
}).catch(function(err) {
console.log(err);
});
Sending transactions is similar, but uses an event emitter for receiving the transaction hash, receipt, etc.

For anyone else struggling, try to check whether your ABI json actually includes the method you are trying to call. It could have been that you copied the ABI for the wrong contract as Remix would by default list the first contract in the default template rather than your newly created contract.

This is a new language for me so my error came when I copied the abi into my variable and it pasted an extra set of "[]" so it looked something like:
const abi = [[...]];
If I'm correct, it should be:
const abi = [...];
with only single set of the most outer square brackets. This is probably only a mistake for someone like myself who is still learning the syntax of this language.

There is actually a simple fix to this:
I was using express and web3 together but web3 1.0.0-beta was the issue. You just have to install a stable version such as 0.19.0 or 0.20.0
npm install web3#^0.19.0 --save
Then it will work.

Related

Undefined variable, nodejs, json to program variable

I decided to save data the dirty way to a .json file. For some reason, when I run my index.js file which runs other modules I have written, it says that a particular variable I initialized in a separate module is undefined (one I was hoping to reference from json). The structure of my program is the standard index file that loads functions from modules I have written and executes them via endpoints.
.json File
{"blocks":[{"GENESIS_DATA":{"timestamp":1,"lastHash":"v01d","hash":"?M=(((Position-1)=>ter)=>sen)=>non?","difficulty":20,"nonce":0,"data":[]}}]}
I want to take the first index of this array named GENESIS_DATA and use it as an array in my program...
relevant code from blockchain index (not the file I execute for the program to run)
const { REWARD_INPUT, MINING_REWARD, GENESIS_DATA } = require('../config');
const fs = require('fs');
const jsonRoute = '/home/main/public_html/Cypher-Network/CDSM/CDSM.json';
class Blockchain {
constructor() {
fs.readFile(jsonRoute, 'utf-8', function(err, data) {
if (err) throw err;
this.jsonChain = JSON.parse(data);
const genesis = jsonChain.blocks[0];
});
this.chain = [genesis];
}
/*Alot more code down here but let's assume that the bracket for class Blockchain is completed*/
}
error log
/home/main/public_html/Cypher-Network/blockchain/index.js:32
this.chain = [genesis]; //we are taking the first element of the json file (genesis block)
^
ReferenceError: genesis is not defined
at new Blockchain (/home/main/public_html/Cypher-Network/blockchain/index.js:32:19)
at Object.<anonymous> (/home/main/public_html/Cypher-Network/index.js:28:20)
at Module._compile (internal/modules/cjs/loader.js:1158:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
at Module.load (internal/modules/cjs/loader.js:1002:32)
at Function.Module._load (internal/modules/cjs/loader.js:901:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
at internal/main/run_main_module.js:18:47
main#goldengates.club [~/public_html/Cypher-Network]#
First, the constant genesis is local to the callback, so it is getting destroyed just after the callback has finished running.
Also even if the constant was declared outside the callback, remember that fs.readFile is asynchronous, so while readFile is reading the file containing the data, the constant genesis will have already been set to undefined.

How to manage multiple .js files so as to run automated test cases using their tags in CucumberJS?

I am using CucumberJS with Selenium-Webdriver for automating my test cases. Currently I am having multiple feature files with their respective step-definition files. When I am trying to run the test cases then it is throwing an error:
Error: The previously configured ChromeDriver service is still
running. You must shut it down before you may adjust its
configuration.
at Object.setDefaultService (D:\code\egov-test-cases\node_modules\selenium-webdriver\chrome.js:305:11)
at new World (D:\code\egov-test-cases\features\support\world.js:21:12)
at Object. (D:\code\egov-test-cases\features\steps\create_approver_remittance_master.js:15:13)
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Module.require (module.js:597:17)
at require (internal/module.js:11:18)
at supportCodePaths.forEach.codePath (D:\code\egov-test-cases\node_modules\cucumber\lib\cli\index.js:142:42)
at Array.forEach ()
at Cli.getSupportCodeLibrary (D:\code\egov-test-cases\node_modules\cucumber\lib\cli\index.js:142:22)
at D:\code\egov-test-cases\node_modules\cucumber\lib\cli\index.js:169:41
at Generator.next ()
at asyncGeneratorStep (D:\code\egov-test-cases\node_modules\cucumber\lib\cli\index.js:44:103)
error Command failed with exit code 1. info Visit
https://yarnpkg.com/en/docs/cli/run for documentation about this
command.
Since I am automating the tests, I have put the below code for automating chrome in world.js file, and then tried importing the driver from world.js, but still it is giving the same error.
class World {
constructor() {
const { setDefaultTimeout } = require('cucumber');
const webdriver = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const path = require('chromedriver').path;
const screen = {
width: 640,
height: 480
};
setDefaultTimeout(100 * 5000);
var service = new chrome.ServiceBuilder(path).build();
chrome.setDefaultService(service);
this.driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build();
}
}
What you may need to do is kill your browser after each test run as the containers are reused(hence why a browser may already be running). To do this you will want to add a hooks file to your support folder and include something as follows
After({}, async function(scenario) {
this.driver.quit();
}
});
for more info take a look at the docs https://github.com/cucumber/cucumber-js/blob/master/docs/support_files/hooks.md
I found the solution to my problem. Actually the driver was getting initialized multiple times and that is why it was giving me the above error. I was creating the driver inside the constructor in the class World in world.js file. Everytime i was taking an instance of the class World, I was creating a new driver. I shifted the driver declaration outside the class as const driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build() and created a method as initialize() { return driver; } in world.js file. I am calling the initialize() method in my step definition files as let world = new World(); let driver = world.initialize(). Now I am good to go!

Merging stack traces in rethrown errors

I'm rethrowing here an error from Sequelize promise (Bluebird). In the first place, this was done to change error message, but as it appeared, this also produces more informative stack trace.
It is something like
sequelize.sync().catch(originalError => {
const rethrownError = new Error(originalError.msg + ': ' + originalError.sql);
throw rethrownError;
});
Where originalError.stack doesn't contain the line that caused the error but it holds important information that it originates in Sequelize and MySQL driver:
SequelizeDatabaseError: ER_KEY_COLUMN_DOES_NOT_EXITS: Key column 'NonExisting' doesn't exist in table
at Query.formatError (...\node_modules\sequelize\lib\dialects\mysql\query.js:175:14)
at Query._callback (...\node_modules\sequelize\lib\dialects\mysql\query.js:49:21)
at Query.Sequence.end (...\node_modules\mysql\lib\protocol\sequences\Sequence.js:85:24)
at Query.ErrorPacket (...\node_modules\mysql\lib\protocol\sequences\Query.js:94:8)
at Protocol._parsePacket (...\node_modules\mysql\lib\protocol\Protocol.js:280:23)
at Parser.write (...\node_modules\mysql\lib\protocol\Parser.js:74:12)
at Protocol.write (...\node_modules\mysql\lib\protocol\Protocol.js:39:16)
at Socket.<anonymous> (...\node_modules\mysql\lib\Connection.js:109:28)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at readableAddChunk (_stream_readable.js:176:18)
at Socket.Readable.push (_stream_readable.js:134:10)
at TCP.onread (net.js:548:20)
rethrownError.stack contains the point of interest (the first line in the stack) but everything else is a rubbish:
Error: ER_KEY_COLUMN_DOES_NOT_EXITS: Key column 'NonExisting' doesn't exist in table
at sequelize.sync.catch (...\app.js:59:17)
at tryCatcher (...\node_modules\bluebird\js\release\util.js:16:23)
at Promise._settlePromiseFromHandler (...\node_modules\bluebird\js\release\promise.js:504:31)
at Promise._settlePromise (...\node_modules\bluebird\js\release\promise.js:561:18)
at Promise._settlePromise0 (...\node_modules\bluebird\js\release\promise.js:606:10)
at Promise._settlePromises (...\node_modules\bluebird\js\release\promise.js:681:18)
at Async._drainQueue (...\node_modules\bluebird\js\release\async.js:138:16)
at Async._drainQueues (...\node_modules\bluebird\js\release\async.js:148:10)
at Immediate.Async.drainQueues (...\node_modules\bluebird\js\release\async.js:17:14)
at runCallback (timers.js:637:20)
at tryOnImmediate (timers.js:610:5)
at processImmediate [as _immediateCallback] (timers.js:582:5)
I would like to keep the information about both of them - and to designate the link between them, not just to add as two unrelated log entries.
I've been thinking on logging them as a single error with concatenated stack, rethrownError.stack += '\n' + originalError.stack.
How should these two errors be treated? Should their stack traces be joined? Is there a convention for merging error stacks in JavaScript (Node.js in particular)?
The intention is to keep the resulting error meaningful and to not upset existing tools that parse error stack traces (namely Stacktrace.js).
The projects under consideration use Winston logger or plain console.error, so the error is stringified at some point (in the example above it was logged via unhandled rejection handler).
🚨 UPDATE 2022: Error.prototype.cause has been implemented in ES2022. Consider using the native implementation.
Since ECMAScript 2022, new Error() lets us specify what caused it:
function readFiles(filePaths) {
return filePaths.map(
(filePath) => {
try {
// ···
} catch (error) {
throw new Error(
`While processing ${filePath}`,
{cause: error}
);
}
});
}
See also: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
Original answer:
Here is a lightweight alternative to VError: rerror
(I’m the author)
The idea is the same: Wrapping errors in errors. However it is much simpler. It has less features, but also works in the browser. It also takes into account that creating stack traces is expensive. Instead of creating stack traces and appending them to a string it creates a stack of errors internally and only creates the big stack trace if you need it (use the getter).
Example
function fail() {
throw new RError({
name: 'BAR',
message: 'I messed up.'
})
}
function failFurther() {
try {
fail()
} catch (err) {
throw new RError({
name: 'FOO',
message: 'Something went wrong.',
cause: err
})
}
}
try {
failFurther()
} catch (err) {
console.error(err.why)
console.error(err.stacks)
}
Output
FOO: Something went wrong. <- BAR: I messed up.
Error
at failFurther (/Users/boris/Workspace/playground/es5/index.js:98:11)
at Object.<anonymous> (/Users/boris/Workspace/playground/es5/index.js:107:3)
at Module._compile (module.js:556:32)
at Object.Module._extensions..js (module.js:565:10)
at Module.load (module.js:473:32)
at tryModuleLoad (module.js:432:12)
at Function.Module._load (module.js:424:3)
at Module.runMain (module.js:590:10)
at run (bootstrap_node.js:394:7)
<- Error
at fail (/Users/boris/Workspace/playground/es5/index.js:88:9)
at failFurther (/Users/boris/Workspace/playground/es5/index.js:96:5)
at Object.<anonymous> (/Users/boris/Workspace/playground/es5/index.js:107:3)
at Module._compile (module.js:556:32)
at Object.Module._extensions..js (module.js:565:10)
at Module.load (module.js:473:32)
at tryModuleLoad (module.js:432:12)
at Function.Module._load (module.js:424:3)
at Module.runMain (module.js:590:10)
A recommended read: https://www.joyent.com/node-js/production/design/errors
As far as I know, there is no built-in way to handle nested errors in Node.js. The only thing I can recommend you is to use the VError library. It is really useful when dealing with advanced error handling.
You can use fullStack to combine stack traces of many errors:
var err1 = new VError('something bad happened');
var err2 = new VError(err1, 'something really bad happened here');
console.log(VError.fullStack(err2));
Building upon https://stackoverflow.com/a/42147148/1703845, I abstracted the VError.fullStack call away like this
class FullStackVError extends VError {
constructor(cause, ...args) {
super(cause, ...args);
let childFullStack;
if (cause instanceof VError) {
childFullStack = cause.stack;
cause.stack = cause._originalStack;
}
this._originalStack = this.stack;
this.stack = VError.fullStack(this);
if (cause instanceof VError) {
cause.stack = childFullStack;
}
}
}
Now console.log(err2.stack); is equivalent to what console.log(VError.fullStack(err2)); would have been.

WebDriverError: Cannot find elements when the xpath expression is null in javascript

I'm testing a login page on the remote server and selenium throws me the above error. But when I test the same code on a local server, it works perfectly. I'm unable to understand as to why the remote server would throw an error and the local server won't when the selenium version on both sites is exactly the same.
Initially, I used:
browser.driver.findElement(By.xpath(desiredXpath)).click()
to click on any button. Then I tried to make a method which only performs the click operation so that every click operation could be performed by this method itself. For that I used:
browser.executeScript('arguments[0].click()', driver.findElement(By.xpath(desiredXpath)))
The above line executes perfectly on a local server but fails to recognise the xpath on the remote server and hence throws an error, WebDriverError: Cannot find elements when the xpath expression is null.
I used a console statement to print the xpath just before this line executes. It prints the xpath through which the element is to be located.
Any suggestions?
You might need to wait for the element to become present:
var elm = element(by.xpath(desiredXpath));
var EC = protractor.ExpectedConditions;
browser.wait(EC.presenceOf(elm), 5000);
elm.click();
// or browser.executeScript("arguments[0].click();", elm.getWebElement());
My two cents on this ... I am reporting my observation below. I was able to reproduce the above stated error by passing null in xpath of theelementFinder which was passed as an argument in browser.executeScript
The below code when executed with a = null throws the error we are looking out for
it('check', function () {
browser.get("http://www.protractortest.org/");
//var a = "//a[contains(#class,'github')]";
var a = null;
browser.executeScript('arguments[0].click()', element(by.xpath(a)))
});
Error Stack
Stack:
WebDriverError: Cannot find elements when the XPath expression is null.
at WebDriverError (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\error.js:27:10)
at Object.checkLegacyResponse (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\error.js:639:15)
at parseHttpResponse (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\http\index.js:538:13)
at C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\http\index.js:472:11
at ManagedPromise.invokeCallback_ (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:1379:14)
at TaskQueue.execute_ (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2913:14)
at TaskQueue.executeNext_ (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2896:21)
at C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2820:25
at C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:639:7
at process._tickCallback (node.js:369:9)
From: Task: WebDriver.findElements(By(xpath, null))
at WebDriver.schedule (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\webdriver.js:377:17)
at WebDriver.findElements (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\webdriver.js:926:22)
at C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\built\element.js:161:44
at ManagedPromise.invokeCallback_ (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:1379:14)
at TaskQueue.execute_ (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2913:14)
at TaskQueue.executeNext_ (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2896:21)
at C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2775:27
at C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:639:7
at process._tickCallback (node.js:369:9)
From: Task: WebDriver.executeScript()
at WebDriver.schedule (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\webdriver.js:377:17)
at WebDriver.executeScript (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\webdriver.js:526:16)
at ProtractorBrowser.to.(anonymous function) [as executeScript] (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\built\browser.js:59:29)
at Object.<anonymous> (C:\Users\aditya\WebstormProjects\demo\demo2.js:10:17)
at C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:94:23
at new ManagedPromise (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:1082:7)
at controlFlowExecute (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:80:18)
at TaskQueue.execute_ (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2913:14)
at TaskQueue.executeNext_ (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2896:21)
at C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2820:25
From: Task: Run it(" through Gmail Account") in control flow
at Object.<anonymous> (C:\Users\aditya\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:79:14)
From asynchronous test:
Error
at Suite.<anonymous> (C:\Users\aditya\WebstormProjects\demo\demo2.js:5:5)
at Object.<anonymous> (C:\Users\aditya\WebstormProjects\demo\demo2.js:4:1)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
1 spec, 1 failure
Finished in 1.957 seconds
Possible Root Cause could be the variable desiredXpath is being passed null and we cannot go with console.log() as they are not in sync with protractor Control flow and anything could have happened in between

Node.js https.createServer throws TypeError: listener must be a function

I've read posts all over concerning this and I know it must be something silly, but I can't figure out why the following code is throwing "TypeError: listener must be a function"
Assume options
var server = https.createServer(options, function(request,response){
if (request.url==='/') request.url='/home/altronic/Opti-Cal/web/arimonitor.htm';
console.log("Request: " + request.url);
fs.readFile("public"+request.url,function(error,data){
if (error) {
response.writeHead(404, {"Content-type":"text/plain"});
response.end ("Sorry the page you requested was not found.");
} else {
response.writeHead(200,{"Content-type":mime.lookup('public'+request.url)});
response.end (data);
}
})
}).listen(port);
Console output:
events.js:130
throw TypeError('listener must be a function');
^
TypeError: listener must be a function
at TypeError (<anonymous>)
at Server.EventEmitter.addListener (events.js:130:11)
at new Server (http.js:1816:10)
at Object.exports.createServer (http.js:1846:10)
at Object.<anonymous> (/home/altronic/Opti-Cal/src/Opti-Cal_HTTPS_Server.js:42:20)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
Can anyone help me figure this out?
Where do you assign https? It looks like you’re probably requiring http, not https. http.createServer doesn’t accept options like https.createServer.
You may hit this error when using a node version < 9.6
See the docs and history. I was very confused that the docs said I could use an options object on http.createServer and got this error until I realized I hadn't updated node in a while.
https://nodejs.org/api/http.html#http_http_createserver_options_requestlistener
I had the same error message:
throw TypeError('listener must be a function');
I have two separate files server.js and handler.js.
My problem was whilst I was requiring ( require(./handler.js) )my handler file in server.js I was not exporting it from handler.js file. You must have: module.exports =handler; at the bottom of your handler file
This is mostly coming from a version mismatch. Latest versions of nodejs's http.createServer() do take options in parameters like https does.

Categories

Resources