Testing http.Server.close error in NodeJS - node.js

I have a code in NodeJS responsible to close an http.Server connection and I would like to test the error scenario on the http.Server.close() method.
The problem is to do that, I need to simulate the return of the close method with the err object populated, and I don't know how to do it.
Below you can find my code and I would like to test the line where we can find the code reject(err);
Note: In my integration tests, I'm starting temp HTTP servers to simulate the real scenario. So as far as I understood I need to find a real scenario where the .close method will be rejected by the default implementation.
Thanks.
this._httpServer = http.createServer((req: http.IncomingMessage, res: http.ServerResponse) => this.handler(req, res));
...
disconnect(): Promise<void> {
return new Promise((resolve, reject) => {
this._httpServer.close((err) => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
}

I found the answer.
Based on the official documentation, the unique error scenario is when we are trying to close an already closed server.
So, to make the test work, before calling my disconnect method I only need to close the httpServer (this._httpServer.close()).
Reference: https://nodejs.org/docs/latest-v12.x/api/net.html#net_server_close_callback

Related

io.connect() is not working and i can't figure what is the problem

[and this is the angular code ][1] this is my node js code
Please copy/paste your actual code. Screenshots are discouraged on SO.
Be sure to include ERROR HANDLING in all of your I/O operations. For example:
https://socket.io/docs/v4/client-initialization/
socket.on("connect_error", (err) => {
if (err.message === "invalid credentials") {
socket.auth.token = "efgh";
socket.connect();
}
});
... or ...
https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/onerror
webSocket.onerror = function(event) {
console.error("WebSocket error observed:", event);
};
Your next step is to get a viable error message.
Please review the library's documentation to determine the "best" way to catch and handle errors for your particular application.

Best way to handle errors in NodeJS

I started working with NodeJS a couple weeks ago. I am wondering what is the best way to handle errors in NodeJS?
Right now, I am doing it in all my controllers methods. For example:
exports.myMethod = async (req, res, next) => {
try {
// My method operations here
} catch(err) {
const email = new Email(); // This is a class that I create to notify me when an error happens. errorEmail(mailBody, mailSubject)
await email.errorEmail(err, "Email Subject - Error");
}
}
Is it a good way? I mean, is there a better/more efficient way to handle errors in NodeJS?
Thanks
Error handling when using Promises (or async/await) is pretty straight forward. You don't want to have lots of duplicates of error handling code and extra try/catch blocks all over the place.
The way I find best is to put the error handling at the highest possible level (not deep in the code). If an exception is thrown, or a Promise rejects, then the failure will percolate up to the point where you catch it and handle it. Everything in between doesn't have to do that if it's handled once at the appropriate place.
So your code can start looking cleaner like this:
// module #1
exports.myMethod = async () => {
// My method operations here
return result;
}
// module #2
exports.anotherMethod = async () => {
const result = await module1.myMethod();
// do more stuff
return anotherResult;
}
// module #3
exports.topMethod = () => {
module2.anotherMethod()
.then((res) => {
console.log("all done", res);
})
.catch((err) => {
const email = new Email(); // This is a class that I create to notify me when an error happens. errorEmail(mailBody, mailSubject)
email.errorEmail(err, "Email Subject - Error")
.then(() => console.log("done, but errors!", err);
});
}
The nice thing here is that the only place I have to add extra error handling is way at the top. If anything deep in the code fails (and it can get much more deep) then it will just return up the chain naturally.
You are free to put .catch statements anywhere in between for doing retries, or to handle expected errors quietly if you want, but I find using .catch is cleaner that wrapping sections of code with try/catch blocks.

Where to Put subscription.pull when want to get the publish data Google Cloud pub/sub NODE JS

So i've tried to develop some pub/sub system based on node js
i am using express post request to publish the data that i wanted. it's send the data well, but my question is where should i put my code for the subscription
Right now i put the code at the root of my file like this
pubSub.subscribe()
.then(({results, subscription}) => {
results[0].data.forEach((item) => {
let key = ['UserId', fakeId(1, 100), 'FeedId', fakeId(100, 200), 'plugin', fakeId(1, 100)]
upsert(key, item, () => {
console.log('Sync Success')
console.log(item)
}, error => console.error(error))
})
subscription.ack(results.map((result) => result.ackId));
})
.catch(error => console.error(error))
i have some helper to subscribe like this
function subscribe () {
const subscription = pubSub.subscription('plugin_subscription')
return new Promise ((resolve, reject) => {
return subscription.pull((error, results) => {
console.log('ini ke trigger')
if (error) reject(error)
resolve({results, subscription})
})
})
}
well it's kind of only work once. if i publish message i dont' have any response log from the subscriber, but if i restart the node js server my log is show that i successfully receive the data and could proceed to the next step.
Am i doing something wrong here?
thanks a lot man
A couple ideas:
You're using promises to handle received messages. A promise on its
own can only be triggered once - to trigger it multiple times, you'd
need some sort of loop or recursive call.
Try using event
handlers (see this example) instead of promises - those should trigger every time an
event occurs without any additional looping or recursion. Note that for this example, you'll need to remove the code that removes the messageHandler listener.
Hopefully this helps!

MongoClient on error event

I am using Node/Mongo and want to capture all MongoErrors so that I can transform then into another error format. I am looking to do this at the base level but cannot figure it out.
Here's my connection setup:
let connection = false
// Create a Mongo connection
export function getConnection () {
if (!connection) {
connection = MongoClient.connect(config.db.mongo.uri, {
promiseLibrary: Promise //Bluebird
})
}
return connection
}
// Fetch a connection for a collection
export function getCollection (collection) {
return getConnection().then(c =>
c.collection(collection)
)
}
I've tried adding on('error') to both connection and MongoClient as well as MongoClient.Db but they do not have that method. I've additionally added a catch block to my getCollection but the errors do not seem to hit it (I am testing with the MongoError 11000 for duplicate fields.
It seems that it can be done but haven't figured it out. It may be because I am using promises.
This snippet of code does it for us. I suspect you need to pass in the function that handles the 'error' event as well. Hope it helps someone who stumbles across this question in the future.
MongoClient.connect(database_string, (err, db) => {
this.db.on('error', function() {
console.error("Lost connection to mongodb(error), exiting".bold.red);
return process.exit(1);
}); // deal breaker for now
}

Check for internet connectivity in NodeJs

Installed NodeJS on Raspberry Pi, is there a way to check if the rPi is connected to the internet via NodeJs ?
A quick and dirty way is to check if Node can resolve www.google.com:
require('dns').resolve('www.google.com', function(err) {
if (err) {
console.log("No connection");
} else {
console.log("Connected");
}
});
This isn't entire foolproof, since your RaspPi can be connected to the Internet yet unable to resolve www.google.com for some reason, and you might also want to check err.type to distinguish between 'unable to resolve' and 'cannot connect to a nameserver so the connection might be down').
While robertklep's solution works, it is far from being the best choice for this. It takes about 3 minutes for dns.resolve to timeout and give an error if you don't have an internet connection, while dns.lookup responds almost instantly with the error ENOTFOUND.
So I made this function:
function checkInternet(cb) {
require('dns').lookup('google.com',function(err) {
if (err && err.code == "ENOTFOUND") {
cb(false);
} else {
cb(true);
}
})
}
// example usage:
checkInternet(function(isConnected) {
if (isConnected) {
// connected to the internet
} else {
// not connected to the internet
}
});
This is by far the fastest way of checking for internet connectivity and it avoids all errors that are not related to internet connectivity.
I had to build something similar in a NodeJS-app some time ago. The way I did it was to first use the networkInterfaces() function is the OS-module and then check if one or more interfaces have a non-internal IP.
If that was true, then I used exec() to start ping with a well-defined server (I like Google's DNS servers). By checking the return value of exec(), I know if ping was sucessful or not. I adjusted the number of pings based on the interface type. Forking a process introduces some overhead, but since this test is not performed too frequently in my app, I can afford it. Also, by using ping and IP-adresses, you dont depend on DNS being configured. Here is an example:
var exec = require('child_process').exec, child;
child = exec('ping -c 1 128.39.36.96', function(error, stdout, stderr){
if(error !== null)
console.log("Not available")
else
console.log("Available")
});
It's not as foolproof as possible but get the job done:
var dns = require('dns');
dns.lookupService('8.8.8.8', 53, function(err, hostname, service){
console.log(hostname, service);
// google-public-dns-a.google.com domain
});
just use a simple if(err) and treat the response adequately. :)
ps.: Please don't bother telling me 8.8.8.8 is not a name to be resolved, it's just a lookup for a highly available dns server from google. The intention is to check connectivity, not name resolution.
Here is a one liner: (Node 10.6+)
let isConnected = !!await require('dns').promises.resolve('google.com').catch(()=>{});
Since I was concerned with DNS cache in other solutions here, I tried an actual connectivity test using http2.
I think this is the best way to test the internet connection as it doesn't send much data and also doesn't rely on DNS resolving alone and it is quite fast.
Note that this was added in: v8.4.0
const http2 = require('http2');
function isConnected() {
return new Promise((resolve) => {
const client = http2.connect('https://www.google.com');
client.on('connect', () => {
resolve(true);
client.destroy();
});
client.on('error', () => {
resolve(false);
client.destroy();
});
});
};
isConnected().then(console.log);
Edit: I made this into a package if anyone is interested.
As of 2019 you can use DNS promises lookup.
NOTE This API is experimental.
const dns = require('dns').promises;
exports.checkInternet = function checkInternet() {
return dns.lookup('google.com')
.then(() => true)
.catch(() => false);
};
I found a great and simple npm tool to detect internet connection. It's looks like more reliable.
First you need to install
npm i check-internet-connected
Then you can call it like follows
const checkInternetConnected = require('check-internet-connected');
const config = {
timeout: 5000, //timeout connecting to each server(A and AAAA), each try (default 5000)
retries: 5,//number of retries to do before failing (default 5)
domain: 'google.com'//the domain to check DNS record of
}
checkInternetConnected(config)
.then(() => {
console.log("Internet available");
}).catch((error) => {
console.log("No internet", error);
});
It is very helpful to check internet connection for our browser is available or not.
var internetAvailable = require("internet-available");
internetAvailable().then(function(){
console.log("Internet available",internetAvailable);
}).catch(function(){
console.log("No internet");
});
for more[internet-available][1]: https://www.npmjs.com/package/internet-available
It's a very simple function that does not import any stuff, but makes use of JS inbuilt function, and can only be executed when called, it does not monitor loss/internet connection; unlike some answers that make use of cache, this result is accurate as it does not return cached result.
const connected = fetch("https://google.com", {
method: "FET",
cache: "no-cache",
headers: { "Content-Type": "application/json" },
referrerPolicy: "no-referrer",
}).then(() => true)
.catch(() => false);
call it using await(make sure your'e inside an async function or you'll get a promise)
console.log(await connected);

Resources