I'm used to thinking in Java, and I'm trying to get around node.js. My program should log information when something goes wrong, and I believe that I need to add a lot of templates in my node.js program to get what I got for free in Java.
My question comes down to:
- Is there an easier / non-contour way to get stack-like information in a callback chain? and / or
- Am I to blame for not being able to understand node.js correctly and trying to make asynchronous node.js look more like synchronous Java?
Java example
Here's a noddy Java program that tries (and fails) to connect to the Mongo database: import java.net.UnknownHostException;
import com.mongodb.Mongo; public class Test { public static void main(final String[] args) throws UnknownHostException { final Mongo mongo = a(); } private static Mongo a() throws UnknownHostException { return b(); } private static Mongo b() throws UnknownHostException { return c(); } private static Mongo c() throws UnknownHostException { return new Mongo("non-existent host"); } }
... which gives this useful stack output:
Exception in thread "main" java.net.UnknownHostException: non-existent host at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method) at java.net.InetAddress$1.lookupAllHostAddr(Unknown Source) at java.net.InetAddress.getAddressesFromNameService(Unknown Source) at java.net.InetAddress.getAllByName0(Unknown Source) at java.net.InetAddress.getAllByName(Unknown Source) at java.net.InetAddress.getAllByName(Unknown Source) at java.net.InetAddress.getByName(Unknown Source) at com.mongodb.ServerAddress.updateInetAddress(ServerAddress.java:204) at com.mongodb.ServerAddress.<init>(ServerAddress.java:73) at com.mongodb.ServerAddress.<init>(ServerAddress.java:46) at com.mongodb.Mongo.<init>(Mongo.java:138) at Test.c(Test.java:20) at Test.b(Test.java:16) at Test.a(Test.java:12) at Test.main(Test.java:8)
(In particular, the last 4 lines show me โwhat is happeningโ in my own code at the time the Mongo error occurred.)
Node.js Example
Here is my attempt to rewrite my program in node.js:
a(function (err, mongo) { if (err) { console.log("Something went wrong in main"); console.log(err); } }); function a(callback) { b(function (err, mongo) { if (err) { console.log("Something went wrong in a()"); return callback(err); } return callback(null, mongo); }); } function b(callback) { c(function (err, mongo) { if (err) { console.log("Something went wrong in b()"); return callback(err); } return callback(null, mongo); }); } function c(callback) { var MongoClient = require('mongodb').MongoClient; return MongoClient.connect('mongodb://non-existent host/', function (err, mongo) { if (err) { console.log("Something went wrong in c()"); return callback(err); } return callback(null, mongo); }); }
... which gives this result:
Something went wrong in c() Something went wrong in b() Something went wrong in a() Something went wrong in main [Error: failed to connect to [non-existent host:27017]]
But to get this result, I have to impose a lot of code templates throughout my program, which will hurt the police as my program gets bigger and I have a whole development team.
Is it possible to get this output as a stack in another way? Do you like this conclusion?