Following is my snippet of main.ts
try {
process.on('unhandledRejection', (err) => {
// tslint:disable-next-line:no-console
console.error(err); <------- no console
});
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter(),
);
app.enableCors();
app.useGlobalFilters(new AllExceptionsFilter());
await app.listen(3000, () => {
// tslint:disable-next-line:no-console
console.log('listen callback'); <------- no console
}).then(() => {
// tslint:disable-next-line:no-console
console.log('started'); <------- no console
});
} catch (error) {
// tslint:disable-next-line:no-console
console.log('catch', error); <----- only this gets consoled as undefined
}
My app gets connected to database (verified), just that it doesn't start.
Calling .listen() with a callback argument means this method is going to return undefined. You are trying to call .then() on that undefined value.
You need simply need to change your listen call to this:
await app.listen(3000, () => 'Server running on port 3000...');
BONUS: You can test this yourself by setting that call to listen to a variable and then console log it:
const result = await app.listen(3000, () => 'Server running on port 3000...');
console.log(result);
//undefined
Related
There are other questions similar to this one but not a single one of them helped me visualize my mistake.
I have this code:
function calc() {
return new Promise(resolve => {
setTimeout(() => {
resolve('block finished');
}, 5000);
});
}
async function asyncBlock() {
let result = await calc();
console.log('Result: ' + result);
return result;
}
app.get('/block', (req, res) => {
let result = asyncBlock();
console.log('Already returned the response without the result.');
res.send(result);
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
The execution continues without the await response, giving me this output:
Example app listening on port 3000
Already returned the response without the result.
Result: block finished
Mozilla documentations states that
If a Promise is passed to an await expression, it waits for the
Promise to be fulfilled and returns the fulfilled value.
Mozilla Doc
Your call to AsyncBlock isn't asynchronous.
Try this:
app.get('/block', async (req, res) => {
let result = await asyncBlock();
console.log('Waited for the result');
res.send(result);
})
I'm starting to learn how to test and I'm having some troubles.
I'm trying to run tests on a socket server but I'm not able to send any message, just connecting an receiving sometimes.
Here is what I have:
import { expect } from 'chai';
import { io as Client } from 'socket.io-client';
import { httpServer } from '../src/loader/app.js';
let server;
let socketUrl;
describe('Sockets test cycle', () => {
before(async function () {
server = await startServer();
socketUrl = `http://localhost:${server.address().port}`;
});
after(function () {
server.close();
});
describe('SOCKET', () => {
it('Should receive a message', async () => {
const client = new Client(socketUrl);
const message = {
text: 'Test',
username: 'test#test',
};
client.on('messages', (arg, done) => {
console.log('Receiving message');
expect(arg).to.eql(message);
client.disconnect();
done();
});
//Only with this await I'm able to connect to server.
//await new Promise((r) => setTimeout(r, 1000));
client.on('connect', () => {
client.emit('new-message', message);
console.log('Sending message');
});
});
});
});
async function startServer() {
return new Promise((resolve, reject) => {
const PORT = 0;
const server = httpServer.listen(PORT, () => {
console.log(`Server listening on port ${server.address().port}`);
resolve(server);
});
server.on('error', (error) => {
console.log(`Error on server: ${error}`);
reject(error);
});
});
}
EDIT:
Here is the output:
[2022-04-03T23:03:58.979] [INFO] default - Starting Products Router
[2022-04-03T23:03:58.981] [INFO] default - Starting Carts Router
[2022-04-03T23:03:58.982] [INFO] default - Starting Users Router
[2022-04-03T23:03:58.982] [INFO] default - Starting Orders Router
[2022-04-03T23:03:58.984] [INFO] default - Starting MessageSocketRouter
Sockets test cycle
Server listening on port 53178
SOCKET
✔ Should receive a message
1 passing (20ms)
If I add the await in the middle with 1 second for waiting, I'm able to connect, but that's all I could do.
Could you give me any idea or any hint? I've been reading the oficial documentation but I'm kind of lost.
Thanks!
I am trying to connect to to db then run my server. So I am using aync await like below:
startApp = async()=>{
try {
await mongoose.connect('mongodb+srv://tanvirgeek:<password>#cluster0-e7kwf.mongodb.net/test?
retryWrites=true&w=majority',)
console.log('connected to db');
await app.listen(5000);
console.log('server connected on port 5000')
} catch (error) {
console.log(error);
}
}
app.get('/',(req,res)=>{
res.send("hello world");
})
startApp();
I intentionally gave a wrong db connect URL without a password to get error in the console. In the console I am getting no error and this message:server connected on port 5000.
My desired output is error message in the console, without this successful server running message. How can I achieve this?
you are adding a ',' between your path connection and ')'. In mongoose doc:
mongoose.connect('mongodb+srv://tanvirgeek:<password>#cluster0-e7kwf.mongodb.net/test?
retryWrites=true&w=majority', { useNewUrlParser: true }).
catch(error => handleError(error));
// Or:
try {
await mongoose.connect('mongodb+srv://tanvirgeek:<password>#cluster0-e7kwf.mongodb.net/test?
retryWrites=true&w=majority', { useNewUrlParser: true });
} catch (error) {
handleError(error);
}
source mongoose
I have an LdapJS server which implements standard operation and an extended operation to check health:
const server = ldap.createServer();
server.exop('healthcheck', (req, res, next) => {
res.end();
console.log('ended');
return next();
});
...
Then I wrote a simple client script to ping healthcheck service:
const { createClient } = require('ldapjs');
const client = createClient({
url: 'ldap://localhost:1389',
timeout: 2000,
connectTimeout: 2000
});
client.exop('healthcheck', (err, value, res) => {
if (err) {
console.log(`ERROR: ${err.message}`);
process.exit(1);
}
else {
console.log(`STATUS: ${res.status}`);
process.exit(0);
}
});
The problem is that the exop is correctly received by server (I can see the log inside its callback), but the client always logs: ERROR: request timeout (client interrupt).
Why the request is not correctly terminated?
EDIT
I wrote a mocha test for the exop and it works. Seems that the problem is related to the standalone call in healthcheck script.
describe('#healthcheck()', function () {
before(function () {
server = createServer();
server.listen(config.get('port'), config.get('host'), () => {});
});
after(function () {
server.close();
});
it('should return status 0', function (done) {
const { createClient } = require('ldapjs');
const client = createClient({
url: 'ldap://localhost:1389',
timeout: 2000,
connectTimeout: 2000
});
client.exop('healthcheck', (err, value, res) => {
should.not.exist(err);
res.status.should.be.equal(0);
client.destroy();
return done();
});
});
});
I am trying to handle nodejs http.Server listen error with callback. But the following example will throw.
If I wrap the server.listen function into a try ... catch it works and the callback get called with the error.
Can You please enlighten me, why it doesn't work without try ... catch?
Is there any better way to catch the listen error?
const { createServer } = require('http')
function build(handler, callback) {
const server = createServer((req, res) => handler)
// this will throw RangeError
server.listen(99999, function (err) {
if (err) return callback(err, null)
return callback(null, server)
})
})
Edit: node version: 10.12.0
Answered for Node 13:
If you are expecting errors in the callback, I think this is incorrect. I think specifically in this case, the callback is not called if there is an error.
The key is to instead listen for the 'error' event to be triggered:
async function build(handler, callback) {
const server = createServer((req, res) => handler);
try {
let startFinished = false;
await new Promise((resolve, reject) => {
server.listen(3000, () => {
if (!startFinished) {
startFinished = true;
resolve();
}
});
server.once('error', (err) => {
if (!startFinished) {
startFinished = true;
console.log(
'There was an error starting the server in the error listener:',
err
);
reject(err);
}
});
});
return callback(null, server);
} catch (e) {
// Do with the error e as you see fit
console.log('There was an error starting the server:', e);
}
}
in general node will throw a range error if provided function arguments are out of expected range, you can try/catch in your build function like so and handle it there
function build(handler, callback) {
try {
const server = createServer(handler);
// this will throw RangeError
server.listen(99999, function (err) {
callback(err, server);
});
} catch (e) {
if (e instanceof RangeError) {
// handle your special range rrrors
} else {
// handle all your other errors
}
}
};
also you can pass your handle directly to the createServer, and for you error callback you don't need to return the result of your callback
I liked Charley's answer the best. Allyraza's answer caught the error, but directly to the console as well. Charley's answer bugged me though with the extra variable "startFinished". I found I could avoid this and have the best of both worlds by using err appropriately.
async function build(handler, callback) {
// Creating http Server
const server = http.createServer(handler);
// The key is to instead listen for the 'error' event to be triggered:
// listen EADDRINUSE: address already in use :::3000
try {
await new Promise((resolve, reject) => {
// Listening to http Server
server.listen(3000, (err) => {
if (!err)
resolve();
});
server.once('error', ( err ) => {
if (err) {
//console.log( 'There was an error starting the server in the error listener:', err);
reject(err);
}
});
});
// All good
return callback(null, server);
} catch (e) {
// Return to caller any errors
// console.log('There was an error starting the server:', e );
return callback(e, server);
}
}
// Setting up PORT
const PORT = process.env.PORT || 3000;
build(requestListener, (e, server) => {
if (e) {
console.log(`startServer failed: ${ e }` );
} else {
console.log(`Started server. Listening on PORT: ${ PORT }...` );
}
});