NestJs installation on iisnode and Unhandled promise rejection - node.js

When I try to install NestJs application on IIS-server (with iisnode installed) I always just encounter issue which says
"...Error: listen EADDRINUSE: address already in use :::3450.." (see below)
And, as you can see from the console.log (see below), the NestJs application is first fully initialized and launched, but then comes always the port already in use issue. And it persists no matter how many different ports I try. I have also tried to restart iisnode.exe and killed the process and the port but it does not help. Anyone any experience with this and found the solution?
node dist/main
[32m[Nest] 36096 - [39m09/01/2020, 1:43:54 PM [33m[NestFactory] [39m[32mStarting Nest application...[39m
[32m[Nest] 36096 - [39m09/01/2020, 1:43:54 PM [33m[InstanceLoader] [39m[32mConfigHostModule dependencies initialized[39m[33m +34ms[39m
[32m[Nest] 36096 - [39m09/01/2020, 1:43:54 PM [33m[InstanceLoader] [39m[32mAppModule dependencies initialized[39m[33m +0ms[39m
[32m[Nest] 36096 - [39m09/01/2020, 1:43:54 PM [33m[InstanceLoader] [39m[32mConfigModule dependencies initialized[39m[33m +1ms[39m
hello from NestJs app
[32m[Nest] 36096 - [39m09/01/2020, 1:43:54 PM [33m[RoutesResolver] [39m[32mAppController {}:[39m[33m +13ms[39m
[32m[Nest] 36096 - [39m09/01/2020, 1:43:54 PM [33m[RouterExplorer] [39m[32mMapped {, GET} route[39m[33m +4ms[39m
[32m[Nest] 36096 - [39m09/01/2020, 1:43:54 PM [33m[RoutesResolver] [39m[32mItemsController {/items}:[39m[33m +0ms[39m
[32m[Nest] 36096 - [39m09/01/2020, 1:43:54 PM [33m[RouterExplorer] [39m[32mMapped {/items, GET} route[39m[33m +1ms[39m
[32m[Nest] 36096 - [39m09/01/2020, 1:43:54 PM [33m[RouterExplorer] [39m[32mMapped {/items/:id, GET} route[39m[33m +2ms[39m
[32m[Nest] 36096 - [39m09/01/2020, 1:43:54 PM [33m[RouterExplorer] [39m[32mMapped {/items, POST} route[39m[33m +1ms[39m
[32m[Nest] 36096 - [39m09/01/2020, 1:43:54 PM [33m[RoutesResolver] [39m[32mShoppingCartController {/shopping-cart}:[39m[33m +1ms[39m
[32m[Nest] 36096 - [39m09/01/2020, 1:43:54 PM [33m[RouterExplorer] [39m[32mMapped {/shopping-cart, POST} route[39m[33m +0ms[39m
[32m[Nest] 36096 - [39m09/01/2020, 1:43:54 PM [33m[NestApplication] [39m[32mNest application successfully started[39m[33m +4ms[39m
App is running in port: 61302
events.js:292
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE: address already in use :::61302
at Server.setupListenHandle [as _listen2] (net.js:1313:16)
at listenInCluster (net.js:1361:12)
at Server.listen (net.js:1447:7)
at ExpressAdapter.listen (C:\...\node_modules\#nestjs\platform-express\adapters\express-adapter.js:45:32)
at NestApplication.listen (C:\...\node_modules\#nestjs\core\nest-application.js:146:26)
at async bootstrap (C:\...\dist\main.js:8:9)
Emitted 'error' event on Server instance at:
at emitErrorNT (net.js:1340:8)
at processTicksAndRejections (internal/process/task_queues.js:84:21) {
code: 'EADDRINUSE',
errno: 'EADDRINUSE',
syscall: 'listen',
address: '::',
port: 61302
}
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! nest-restaurant-api#0.0.1 start:prod: `node dist/main`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the nest-restaurant-api#0.0.1 start:prod script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\...\AppData\Roaming\npm-cache\_logs\2020-09-01T12_43_54_285Z-debug.log
In iisnode server error log I can also find the following:
(this proved to be logged in previous day - and not to be seen anymore in the logs. So, this iisnode log message may not be relevant for the issue at all)
(node:45472) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
(node:45472) UnhandledPromiseRejectionWarning: RangeError [ERR_SOCKET_BAD_PORT]: options.port should be >= 0 and < 65536. Received NaN.
at validatePort (internal/validators.js:182:11)
at Server.listen (net.js:1439:5)
at ExpressAdapter.listen (C:\...\node_modules\#nestjs\platform-express\adapters\express-adapter.js:45:32)
at NestApplication.listen (C:\...\node_modules\#nestjs\core\nest-application.js:146:26)
at async bootstrap (C:\...\dist\main.js:7:5)
(node:45472) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:45472) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
In addition here is the /dist/main.js file in its present form (I have added those try / catch -statements).
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("#nestjs/core");
const app_module_1 = require("./app.module");
async function bootstrap() {
try {
const app = await core_1.NestFactory.create(app_module_1.AppModule);
await app.listen(parseInt(process.env.PORT) || 8080)
.catch((e) => {
console.error(e);
process.exit(1);
});
console.log('App is running in port: ' + process.env.PORT);
}
catch (error) {
console.log("Error message: " + error);
}
}
bootstrap().catch(e => {
console.error(e);
});
//# sourceMappingURL=main.js.map

As suggested by Bruce Zhang in his comment I will post the solution I found by myself.
So, the cause of the error was quite silly indeed.
1.) Using Plesk controlling panel (in IIS-server), irrespective of whether the NestJs application is deployed to site root or sub folder (like the default dist folder ), it is essential to get path settings to project to refer correctly:
Now, in the image above, path settings to project are correct when deployed to sub folder (i.e. default build folder dist). My error was that path reference for the Application Startup File was "/dist/main.js" as it should be just main.js.
After this simple correction app started normally with default IIS-port (port 80 and for SSL-protected connection 443). The main.ts -file does not have to anything else than just the following with the IIS default port fetched automatically via process.env.PORT:
import { NestFactory } from '#nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(process.env.PORT);
}
bootstrap();
2.) The second simple thing that must be correctly configured is web.config (and this was originally correct in my case):
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="iisnode" path="dist/main.js" verb="*" modules="iisnode" />
</handlers>
<iisnode nodeProcessCommandLine="C:\Program Files\nodejs\node.exe">
</iisnode>
<rewrite>
<rules>
<rule name="nestjs">
<match url="/*" />
<action type="Rewrite" url="main.js" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
I hope this help those who might get confused with IISnode settings in Plesk. And these settings apply generally to all Node.js applications, they are not limited to NestJs which is just upper level framework on node.js, and particularly much on Express. But error messages in IISNode can sometimes be a bit misleading and it takes some pain to see through them.
NestJs is really awesome and it is great that those who have to, or love to, use IIS can easily deploy super modern NestJs backend apps to IIS-server, thanks to those who implemented IISnode.

Related

Nanoexpress server fails on Heroku & AWS - runs fine locally - cannot trace 'dest.on()' error

Relevant stack-trace below - from Heroku:
2020-04-28T17:49:11.997756+00:00 app[web.1]: Your app is listening on port 14385
2020-04-28T17:49:12.491486+00:00 heroku[web.1]: State changed from starting to up
2020-04-28T17:49:41.748150+00:00 heroku[web.1]: State changed from up to crashed
2020-04-28T17:49:41.649885+00:00 app[web.1]: _stream_readable.js:660
2020-04-28T17:49:41.649896+00:00 app[web.1]: dest.on('unpipe', onunpipe);
2020-04-28T17:49:41.649897+00:00 app[web.1]: ^
2020-04-28T17:49:41.649897+00:00 app[web.1]:
2020-04-28T17:49:41.649898+00:00 app[web.1]: TypeError: dest.on is not a function
2020-04-28T17:49:41.649899+00:00 app[web.1]: at ReadStream.Readable.pipe (_stream_readable.js:660:8)
2020-04-28T17:49:41.649900+00:00 app[web.1]: at SendStream.stream (/app/node_modules/send/index.js:798:10)
2020-04-28T17:49:41.649900+00:00 app[web.1]: at SendStream.send (/app/node_modules/send/index.js:707:8)
2020-04-28T17:49:41.649900+00:00 app[web.1]: at /app/node_modules/send/index.js:774:12
2020-04-28T17:49:41.649901+00:00 app[web.1]: at FSReqCallback.oncomplete (fs.js:172:5)
From AWS (EC2 using a Bitnami instance for NodeJS apps):
Your app is listening on port 8080
_stream_readable.js:666
dest.on('unpipe', onunpipe);
^
TypeError: dest.on is not a function
at ReadStream.Readable.pipe (_stream_readable.js:666:8)
at SendStream.stream (/opt/bitnami/apps/demo/htdocs/node_modules/send/index.js:798:10)
at SendStream.send (/opt/bitnami/apps/demo/htdocs/node_modules/send/index.js:707:8)
at /opt/bitnami/apps/coronavirus-demo/htdocs/node_modules/send/index.js:774:12
at FSReqCallback.oncomplete (fs.js:167:5)
error: Forever detected script exited with code: 1
error: Script restart attempt #1
I see that we seem to be dying on _stream_readable.js:666 where 'dest.on' isn't defined - and I'm way into the weeds of Node at this point - so I'm not sure what I'm looking for, but I find that we're defining this method further down in the file:
https://github.com/nodejs/node/blob/master/lib/_stream_readable.js:852 -
Is this as simple as we're evaluating this _stream_readable file top-down and we haven't defined on() as of line 666 and that's why it's failing?
But why would it work locally? The app runs fine with Nanoexpress server on a Macbook Pro - same package.json and lock files - no devDependencies that make any difference (the only devDependencies are like Mocha and Sinon and Chai for tests)
I've run the app locally with NODE_ENV=production and NPM_CONFIG_PRODUCTION=true (it's a React & Express [Nanoexpress] app) and it boots and I can get what I need running just fine.
It's only when I push to Heroku / AWS that I'm getting this failure. Feels like we're trying to use a function before it's defined...
nanoexpress author here.
nanoexpress works fine on Heroku on my projects, but on AWS did not test, but nanoexpress does not support Lambda/Serverless.
Please check first your code or try PRO version as now it's Free

MongoDB & nodejs with Docker "MongoTimeoutError: Server selection timed out after 30000 ms"

I am using mongoDB with and NodeJS backend. I have Problem and the Problem have docker logs is below.
{ MongoTimeoutError: Server selection timed out after 30000 ms
at Timeout.setTimeout [as _onTimeout] (/usr/src/app/node_modules/mongodb/lib/core/sdam/topology.js:897:9)
at ontimeout (timers.js:436:11)
at tryOnTimeout (timers.js:300:5)
at listOnTimeout (timers.js:263:5)
at Timer.processTimers (timers.js:223:10)
name: 'MongoTimeoutError',
reason:
{ Error: connect ECONNREFUSED 127.0.0.1:27017
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1113:14)
name: 'MongoNetworkError',
errorLabels: [ 'TransientTransactionError' ],
[Symbol(mongoErrorContextSymbol)]: {} },
[Symbol(mongoErrorContextSymbol)]: {} }
(node:1) UnhandledPromiseRejectionWarning: MongoTimeoutError: Server selection timed out after 30000 ms
at Timeout.setTimeout [as _onTimeout] (/usr/src/app/node_modules/mongodb/lib/core/sdam/topology.js:897:9)
at ontimeout (timers.js:436:11)
at tryOnTimeout (timers.js:300:5)
at listOnTimeout (timers.js:263:5)
at Timer.processTimers (timers.js:223:10)
(node:1) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:1) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
This is my Dockerfile
#FROM node:10.12.0
FROM node:latest-alpline
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm#5+)
COPY package.json ./
RUN npm install
# If you are building your code for production
# RUN npm install --only=production
# Bundle app source
COPY . .
EXPOSE 3000
CMD [ "node", "app.js" ]
This is docker-compose.yml
version: "2"
services:
app:
container_name: app_test
restart: always
build: .
ports:
- "3000:3000"
links:
- mongo_test
depends_on:
- mongo_test
networks:
- nodeapp_network
mongo_test:
container_name: mongo_test
image: mongo
volumes:
- ./data:/data/db
ports:
- "27017:27017"
networks:
- nodeapp_network
networks:
nodeapp_network:
driver: bridge
The following code connects mongodb to mongoose in node js:
mongoose.connect('mongodb://mongo_test:27017/collectionName', {useNewUrlParser: true});
I get the same result if I use localhost, 127.0.0.1, IP address instead of mongo_test.
I have consulted several blogs, stack overflows.
How can I do?
(ps. I can't well English, so Please understand even if words are awkward. Thank you.)
There's nothing wrong with the current configuration, after few retries the app.js is connecting to the database
Here's what is happening:
docker-compose is launching Mongodb service, the port is not yet open
docker-compose starts app_test and app_test tries to connect it fails(2 to 3 times)
After a few seconds, Mongodb port is now open on 27017
Since your config has restart: always the node.js app restarts and connects successfully to the database
To avoid these restarts, you can write it like this
setTimeout(function() {
try {
await mongoose.connect('mongodb://mongo_test:27017/collectionName',
{ useNewUrlParser: true }
);
} catch (error) {
console.log('Error connecting - retrying in 30 seconds')
}, 30000); // Wait for 30 seconds and try to connect again
Explanation:
The connectTimeoutMS is a MongoDB Connection Option and it sets the number of milliseconds a socket stays inactive before closing during the connection phase of the driver. That is to say, when the application initiates a connection, when a replica set connects to new members, or when a replica set reconnects to members. the default value is 30000 milliseconds would mean the driver would wait up to 3 seconds for a response from a MongoDB server. link
Compose does not wait until your mongo_test container is “ready”.
The problem of waiting for a database to be ready is really just a subset of a much larger problem of distributed systems. In production, your database could become unavailable or move hosts at any time. Your application needs to be resilient to these types of failures. link
Using depends_on in your app_test service is still no guarantee to establish the connection between your services.
Solution:
You can update your code to connect to MongoDB:
const connectWithRetry = () => {
mongoose
.connect('mongodb://mongo_test:27017/collectionName', {useNewUrlParser: true})
.then(() => console.log("succesfully connected to DB"))
.catch((e) => {
console.log(e);
setTimeout(connectWithRetry, 5000);
});
};
connectWithRetry();

Nest automatically populates the graphql.options.ts with unknown schema

I just followed the documentation and attached prisma to my nest project. The problem is, when I run yarn start:dev it populates the graphql.options.ts with some unknown schema and throws the following error:
[nodemon] starting `ts-node -r tsconfig-paths/register src/main.ts`
[Nest] 50392 - 12/24/2018, 10:08:57 PM [NestFactory] Starting Nest application...
[Nest] 50392 - 12/24/2018, 10:08:57 PM [InstanceLoader] AppModule dependencies initialized +43ms
[Nest] 50392 - 12/24/2018, 10:08:57 PM [InstanceLoader] PrismaModule dependencies initialized +0ms
[Nest] 50392 - 12/24/2018, 10:08:57 PM [InstanceLoader] UsersModule dependencies initialized +1ms
[Nest] 50392 - 12/24/2018, 10:08:57 PM [InstanceLoader] GraphQLModule dependencies initialized +0ms
(node:50392) UnhandledPromiseRejectionWarning: Error: Interface field Vehicle.wheels expects type Int but Car.wheels is type String.
Interface field argument Vehicle.stuff(a:) expects type Int but Car.stuff(a:) is type String.
at assertValidSchema (/Users/pubudu/Projects/nest-prisma-sample/node_modules/graphql/type/validate.js:71:11)
at assertValidExecutionArguments (/Users/pubudu/Projects/nest-prisma-sample/node_modules/graphql/execution/execute.js:146:35)
at executeImpl (/Users/pubudu/Projects/nest-prisma-sample/node_modules/graphql/execution/execute.js:67:3)
at Object.execute (/Users/pubudu/Projects/nest-prisma-sample/node_modules/graphql/execution/execute.js:62:229)
at Object.generateSchemaHash (/Users/pubudu/Projects/nest-prisma-sample/node_modules/apollo-server-core/src/utils/schemaHash.ts:11:18)
at new ApolloServerBase (/Users/pubudu/Projects/nest-prisma-sample/node_modules/apollo-server-core/src/ApolloServer.ts:299:23)
at new ApolloServer (/Users/pubudu/Projects/nest-prisma-sample/node_modules/apollo-server-express/src/ApolloServer.ts:70:1)
at GraphQLModule.<anonymous> (/Users/pubudu/Projects/nest-prisma-sample/node_modules/#nestjs/graphql/dist/graphql.module.js:118:33)
at Generator.next (<anonymous>)
at fulfilled (/Users/pubudu/Projects/nest-prisma-sample/node_modules/#nestjs/graphql/dist/graphql.module.js:16:58)
(node:50392) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:50392) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Here's the sample code:
https://github.com/THPubs/nest-prisma-sample
Any idea what's happening?
The issues is with the GraphQLOptions. In there, according to the examples, I have defined the typePaths as follows:
typePaths: ['./**/*.graphql'],
It looks like this gets all the graphql files in the project even from the node_modules folder. So, to import exactly the file I want, I used the following:
typePaths: ['./src/prisma/prisma-types.graphql'],

I'm trying to deploy a node server to heroku and I'm getting this error: throw er; // Unhandled 'error' event

I'm trying to deploy a node app to heroku and it looks like judging from other questions that heroku is dynamically assigning a port and it is somehow incompatible with something.
(I had to remove some details to post the question)
events.js:182
throw er; // Unhandled 'error' event
^
Error: listen EACCES 0.0.0.0:80
at Object._errnoException (util.js:1041:11)
at _exceptionWithHostPort (util.js:1064:20)
at Server.setupListenHandle [as _listen2] (net.js:1305:19)
at listenInCluster (net.js:1370:12)
at Server.listen (net.js:1466:7)
at Function.listen (/app/node_modules/express/lib/application.js:618:24)
at Object.<anonymous> (/app/index.js:9:21)
at Module._compile (module.js:573:30)
at Object.Module._extensions..js (module.js:584:10)
at Module.load (module.js:507:32)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! TFP#1.0.0 start: `node index.js`
npm ERR! Failed at the TFP#1.0.0 start script.
Problem
I had the same issue. I ran into this problem when I tried to set the port manually:
app.listen(80, function () {
console.log('Example blog app listening on port 80!')
});
This led me to the same EACCES error.
Solution
I was able to solve the problem by going back and looking through the Heroku docs where I found:
The command in a web process type must bind to the port number specified in the PORT environment variable. If it does not, the dyno will not start.
So, assuming you're using express, if you switch the port assignment to look something like this:
app.set('port', (process.env.PORT || 5000));
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
Then you application should start properly.
Solution without Express.js
If you are not using Express, then you can set the port simply as:
var PORT = process.env.PORT || 5000;
Where process.env.PORT will be your production port, and 5000 will be the port you would use when testing your server locally.
I have faced this kind of problem. The exact error is the port 80 is already enabled in another project or app. So before start your app, stop the other app mapped to 80 port.
Now you can run your app without this error.
Thanks

Mocha-allure-reporter not working with node js

I am facing issue when I run my tests with mocha-allure-reporter ,the tests are running successfully with mocha ,but mocha --reporter mocha-allure-reporter returns the following error
> notifications-api#1.0.0 test /app
> mocha --reporter mocha-allure-reporter
2016-11-15T06:13:26.762Z - info: Notification API up and running on port 4000
2016-11-15T06:13:26.773Z - error: Tue, 15 Nov 2016 06:13:26 GMT uncaughtException
2016-11-15T06:13:26.775Z - error: TypeError: test.currentRetry is not a function
at Runner.<anonymous> (/app/node_modules/mocha-allure-reporter/index.js:29:19)
at emitOne (events.js:77:13)
at Runner.emit (events.js:169:7)
at next (/app/node_modules/mocha/lib/runner.js:517:10)
at Runner.runTests (/app/node_modules/mocha/lib/runner.js:556:3)
at /app/node_modules/mocha/lib/runner.js:637:10
at next (/app/node_modules/mocha/lib/runner.js:283:14)
at Immediate._onImmediate (/app/node_modules/mocha/lib/runner.js:319:5)
at processImmediate [as _immediateCallback] (timers.js:383:17)
npm ERR! Test failed. See above for more details.
Can anyone help to fix this issue?
The issues can be resolved by updating your mocha to the latest version probably to v3 or above and allure reporter too. If the issue still persists regarding TypeError: test.currentRetry is not a function , please replace the line of code
if (!test.currentRetry()) {
with the following
if (typeof test.currentRetry !== "function" || !test.currentRetry()) {

Resources