SDK throws unhelpful NPE when server is unreachable
When trying to create the client via the Java SDK, let's assume I'm connecting to a single node to make it simple. If that node is offline (say I forgot to start the Windows service on my dev machine :), instead of getting a useful error message that describes the issue in a way that allows me to troubleshoot it, I receive a generic Null Pointer Exception with this stack trace:
at ortus.extension.cache.couchbase.CouchbaseCache.init(Unknown Source):-1
Now, if I look in my log files, will see the useful information below:
2013-06-30 15:24:39.168 WARN com.couchbase.client.vbucket.ConfigurationProviderHTTP: Connection problems with URI http://localhost:8091/pools ...skipping
java.io.IOException: Timed out while reading configuration over HTTP
at ortus.extension.cache.couchbase.CouchbaseCache.init(Unknown Source)
Caused by: java.net.SocketTimeoutException: connect timed out
at java.net.TwoStacksPlainSocketImpl.socketConnect(Native Method)
Why can't the uber-useful error from the log file be the error that is thrown from the library? I sifted through the Couchbase libraries a bit and it appears that there is basically a loop where Couchbase attempts to connect to each of the nodes that are specified. If one node errors, it just logs that error and moves on to the next one. I think that is well and good-- as long as at least one of my nodes respond. In the event that ALL nodes error, I would like to see a more useful error be thrown to the application. The NPE looks like the client doesn't do very good checking and attempts to turn around and use the buckets without bothering to check and see if at least one of them were connected to successfully.
I would recommend that if a node connections fails, AND it was the last node to try, AND no other nodes successfully made a connection-- the client stop right there and throw the exception from the last node connection attempt, or at least wrap the exception in another explaining that none of the nodes can be connected to and include the last connection Throwable as the cause.