Hello :) I am trying to setup integration tests for my Express web app.
To start the API/backend servers locally, I have two scripts in package.json:
"dev-api": "cross-env BACKEND_HOSTNAME=localhost ts-node-dev --respawn api-index.ts",
"dev-backend-default": "cross-env CUSTOMER_NAME=default BACKEND_HOSTNAME=localhost ts-node-dev --respawn backend-index.ts",
When running integration tests, I start and kill the servers like so:
async function runTests() {
try {
const api = exec("npm run dev-api"); // Start API server
for (const siteVersion of siteVersions) {
const frontend = exec(`npm run dev-backend-${siteVersion}`); // Start correct version of backend server
// Wait for servers to start
let driver = null;
await new Promise((resolve, reject) => {
setTimeout(() => {
driver = initDriver("firefox");
runAllTests(driver).then(((resolve) => {
resolve();
}).bind(null, resolve));
}, 5000, resolve);
});
console.log("Killing frontend server for siteVersion: ", siteVersion);
exec('taskkill /F /T /PID ' + frontend.pid);
}
console.log("Killing API server");
exec('taskkill /F /T /PID ' + api.pid);
} catch (err) {
console.log(err);
}
}
The tests run, I get all the way down to the logging for killing the servers.
However, node is still running after the servers were "killed". And when I try to start up the API server locally, with my dev script in package.json, it tells me:
Error: listen EADDRINUSE: address already in use :::8081
at Server.setupListenHandle [as _listen2] (net.js:1331:16)
at listenInCluster (net.js:1379:12)
at Server.listen (net.js:1465:7)
at Function.listen (C:\Users\s0116213\Documents\Work\DownloadWebsite\node_modules\express\lib\application.js:635:24)
at C:\Users\s0116213\Documents\Work\DownloadWebsite\controllers\apiController.ts:88:6
at Generator.next (<anonymous>)
at C:\Users\s0116213\Documents\Work\DownloadWebsite\controllers\apiController.ts:31:71
at new Promise (<anonymous>)
at __awaiter (C:\Users\s0116213\Documents\Work\DownloadWebsite\controllers\apiController.ts:27:12)
at startApi (C:\Users\s0116213\Documents\Work\DownloadWebsite\controllers\apiController.ts:51:12)
[ERROR] 13:41:29 Error: listen EADDRINUSE: address already in use :::8081
I also tried shutting down the servers with frontend.kill() and api.kill(), but it didn't change anything.
Is there a way to kill node when it's started this way?
Related
I've set up AWS lambda with some NodeJS code to learn creating an API. API is set up using Express. The runtime is v18. I also set up API Gateway HTTP API with the lambda integration to invoke it.
When I try to call GET method on the /collage route I get internal server error and the Lambda logs return the following:
ERROR Uncaught Exception
{
"errorType": "Error",
"errorMessage": "listen EADDRINUSE: address already in use /tmp/server-undefined.sock",
"code": "EADDRINUSE",
"errno": -98,
"syscall": "listen",
"address": "/tmp/server-undefined.sock",
"port": -1,
"stack": [
"Error: listen EADDRINUSE: address already in use /tmp/server-undefined.sock",
" at Server.setupListenHandle [as _listen2] (node:net:1468:21)",
" at listenInCluster (node:net:1533:12)",
" at Server.listen (node:net:1632:5)",
" at Function.listen (/var/task/node_modules/express/lib/application.js:635:24)",
" at startServer (/var/task/node_modules/#vendia/serverless-express/src/index.js:138:17)",
" at proxy (/var/task/node_modules/#vendia/serverless-express/src/index.js:191:14)",
" at Server.<anonymous> (/var/task/node_modules/#vendia/serverless-express/src/index.js:192:32)",
" at Server.emit (node:events:513:28)",
" at emitListeningNT (node:net:1519:10)",
" at process.processTicksAndRejections (node:internal/process/task_queues:81:21)"
]
}
Here is my code:
const express = require('express');
const { proxy } = require('aws-serverless-express');
const app = express();
app.get('/collage', (req, res) => {
const response = {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: 'Hello, World!' })
};
return response;
});
exports.handler = (event, context) => {
return proxy(app, event, context);
};
The code is as basic as it gets and I put it ogether using some example tutorials and GPT3. Not really sure what could be the issue or how to debug it. There should be no port conflicts since it runs in Lambda..
I did accidentaly include app.listen(3000, () =>{}); before when I deployed the initial version. But it has since been fixed and lambda re-deployed. To make sure I even created a new lambda and deployed latest version to it and got same error.
I tried searching this error on the web, but everyone recommends killing the process, but this is running in lambda so not really possible.
What can I do to debug this?
You are using a deprecated package aws-serverless-express.
You should use serverless-express
On 11/30, the AWS Serverless Express library is moving to Vendia and will be rebranded to serverless-express. Similarly, the aws-serverless-express NPM package will be deprecated in favor of a new serverless-express package.
We used to start Angular and NestJS (based on node.js) projects using Docker containers. This solution was discontinued for various reasons, so we are looking for a way to start these projects at the start of the PC (or on a trigger) and restart the project automatically if a crash occurs.
node-windows
This package builds a Windows service from a node.js project. NestJS being based on node.js, starting it using node.js is done this way (while in the project's folder):
node PATH_TO_PROJECT\node_modules\#nestjs\cli\bin\nest.js start --config .\tsconfig.build.json
The script used:
const svc = new Service({
name: 'Test',
description: 'Test',
script:
'PATH_TO_PROJECT\\node_modules\\#nestjs\\cli\\bin\\nest.js',
scriptOptions: [
'start --watch --config PATH_TO_PROJECT\\tsconfig.build.json',
],
],
execPath: 'C:\\Program Files\\nodejs\\node.exe',
});
svc.on('install', function () {
console.log('installed');
svc.start();
});
svc.install();
The installation works as intended but in a browser, the server cannot be reached.
Questions
Is there a way to use node-windows for a NestJS project?
Is it possible to use an absolute path with the nest cli start command? (e.g nest start --config ABSOLUTE_PATH)
How would you start an Angular project the same way?
Thank you.
am use 'child_process' lib for run command
like this
server.js
const { exec } = require("child_process");
exec("npm run start", (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
and use node-windows like this
var Service = require('node-windows').Service;
var serviceDetail = require('./servicename')();
console.log(serviceDetail);
// Create a new service object
var svc = new Service({
name: serviceDetail.name,
description: serviceDetail.detail,
script: './server.js'
});
console.log('start building up service name ' + serviceDetail.name);
// Listen for the "install" event, which indicates the
// process is available as a service.
svc.on('install',function(){
svc.start();
});
svc.install();
I am trying to run my node/express app on AWS EC2 but am getting errors from Redis, it will not connect to the server and I am not sure what the problem is??
Here is the error I get after the command "npm run production"
Is there a special configuration when running Redis remotely vs locally?
Thank you!
ERROR
[ec2-user#ip-000-00-00-00 application-node-app]$ npm run production
> task-manager#1.0.0 production
> env-cmd -f ./config/prod.env nodemon src/index.js
[nodemon] 2.0.6
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node src/index.js`
server is live on port 3000
Error Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED
127.0.0.1:6379
// 9x Redis retry errors, all identical
REDIS CODE
const mongoose = require(`mongoose`)
const redis = require(`redis`)
const util = require(`util`)
const redisUrl = `redis://127.0.0.1:6379`
const client = redis.createClient(redisUrl)
client.hget = util.promisify(client.hget)
const exec = mongoose.Query.prototype.exec
client.on("error", function (err) {
console.log("Error " + err);
});
mongoose.Query.prototype.cache = function(options = {}) {
this.useCache = true
this.hashKey = JSON.stringify(options.key || `default`)
return this
}
mongoose.Query.prototype.exec = async function () {
if (!this.useCache) {
return exec.apply(this, arguments)
}
const key = JSON.stringify(Object.assign({}, this.getQuery(), {
collection: this.mongooseCollection.name
}))
const cacheValue = await client.hget(this.hashKey, key)
if (cacheValue) {
console.log(`cached DATA!`)
const doc = JSON.parse(cacheValue)
return Array.isArray(doc) ? doc.map(d => new this.model(d)) : new this.model(doc)
}
const result = await exec.apply(this, arguments)
client.hset(this.hashKey, key, JSON.stringify(result), `EX`, 10)
return result
}
module.exports = {
clearHash(hashKey) {
client.del(JSON.stringify(hashKey))
}
}
There isn't any change in redis to run it locally or remotely.
What you need to make sure instead is, Do you have connectivity to redis from your EC2 instance.
Worst case you can try installing redis-cli on to the EC2 instance and figure out from there. I believe it might be port forwarding issue or IP Tables issue.
You should of course restart from a fresh EC2 instance once the testing is done.
Edit: One thing I wish to add here though, Even though I said there is no change in redis, make sure that it's bound on 0.0.0.0 and not on 127.0.0.1 and make sure to check the port config
I am trying to test a mock database with Jest and Sequelize. I created this helper function, which runs before each test suite:
export function handleTestDatabase() {
beforeAll(() => {
testDatabase.sequelize.sync().then(() => app.listen(0));
});
afterAll(() => testDatabase.sequelize.close());
}
I create a connection to my Test Database here and want the Server to listen to any port. The reason I don't give it a specific one, is that I am running into these errors:
listen EADDRINUSE :::4001
The helper function was written to tackle this issue, but it doesn't work. Is there some way to run all tests sequentially? Because when being run alone, every test suites completes successfully. I already tried this command, but it did not work:
jest --runInBand
What bothers me even more is that the tests seem to ignore my beforeAll function, because I also get this error:
listen EADDRINUSE :::4001
193 |
194 | _models2.default.sequelize.sync().then(function () {
> 195 | return server.listen(PORT, function () {
196 | if (process.env.LOGGING) {
197 | console.log("Server running on port " + PORT);
198 | console.log("Go to http" + secure + "://localhost:" + PORT + "/graphiql for the Interface");
at dist/index.js:195:17
at tryCatcher (node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (node_modules/bluebird/js/release/promise.js:614:10)
This shouldn't happen, because this is from my index.js file, and it shouldn't be reached when testing, because my test command is:
"test": "ENVIRONMENT=testing jest --verbose",
And I "protect" my app with this clause:
if (ENVIRONMENT != "testing") {
models.sequelize
.sync()
.then(() =>
server.listen(PORT, () => {
if (process.env.LOGGING) {
console.log(`Server running on port ${PORT}`);
console.log(
`Go to http${secure}://localhost:${PORT}/graphiql for the Interface`
);
}
)
.catch(err => {
console.log(err);
server.close();
});
}
I also tried fixing it by writing a recursive listening function which would reopen the app with another port if there is an error, but that also didn't work.
Any help would be really appreciated.
I solved it be using globalSetup and creating the server there.
I am new to smart contract programming, recently installed truffle using npm on Node(version: 6.10.3)
When I run the command truffle init first time, I received this error:
events.js:160
throw er; // Unhandled 'error' event
^
Error: connect ETIMEDOUT 151.101.8.133:443
at Object.exports._errnoException (util.js:1018:11)
at exports._exceptionWithHostPort (util.js:1041:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1086:14)
The next time I run truffle init, I got ths error:
events.js:160
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at exports._errnoException (util.js:1018:11)
at TLSWrap.onread (net.js:568:26)
Any idea on how to resolve this
I was also facing a similar issue when I tried to execute truffle init behind a corporate http proxy and found a workaround.
Modified the cli.bundled.js: replaced https.request with request
Diff:
diff --git a/build/cli.bundled.js b/build/cli.bundled.js
index 01c69e3..aa2605c 100755
--- a/build/cli.bundled.js
+++ b/build/cli.bundled.js
## -202412,12 +202412,8 ## var Init = {
// will fail spectacularly in a way we can't catch, so we have to do it ourselves.
return new Promise(function(accept, reject) {
- var options = {
- method: 'HEAD',
- host: 'raw.githubusercontent.com',
- path: '/trufflesuite/' + expected_full_name + "/master/truffle.js"
- };
- req = https.request(options, function(r) {
+ var request = require('request');
+ request({ method: 'HEAD', uri: 'https://raw.githubusercontent.com/trufflesuite/'+expected_full_name+'/master/truffle.js'}, function (error, r, body) {
if (r.statusCode == 404) {
return reject(new Error("Example '" + name + "' doesn't exist. If you believe this is an error, please contact Truffle support."));
} else if (r.statusCode != 200) {
## -202425,7 +202421,6 ## var Init = {
}
accept();
});
- req.end();
});
}).then(function() {
## -212634,4 +212629,4 ## module.exports = require("solc");
module.exports = require("string_decoder");
/***/ })
-/******/ ]);
\ No newline at end of file
+/******/ ]);
Prerequisite:
Install request via npm (npm install -g request)
Proxy - setup enviroment as described here
Without code it is pretty difficult to say where this goes wrong. But do you have a ethereum rpc node running on the port specified in the truffle configuration.
Truffle configuration
When inspecting your error code I see you try to connect to 151.101.8.133:443 is there an rpc node running on this port?