-1

I've recently started playing around with Aerospike and their Node driver. I think the database itself is phenomenal, but the client library has a minor hiccup:

// Read the same record from database 
client.get(key, function(err, rec, meta) {
  // Check for errors 
  if ( err.code == status.AEROSPIKE_OK ) {
    // The record was successfully read. 
    console.log(rec, meta);
  } else {
    // An error occurred 
    console.error('error:', err);
  }
});

Instead of returning null or undefined as the error when all went well, an object is always sent back. If err.code === 0 all went well. This means that the library can not be wrapped with bluebird's promisifyAll.

I tried to fix this by adding yet another then-method after each function generated by promisifyAll.

getPromise().then((err, rec, meta) => {
  if(err.code === 0) {
    return {rec: rec, meta: meta};
  } else {
    return Promise.reject();
  }
}

I could not get it to work without explicitly doing it to every function manually. Is there any other way to achieve this?

Tholle
  • 108,070
  • 19
  • 198
  • 189
  • 2
    You could alter the source for the driver, but that's impractical, so maybe you could just wrap it in a new function that returns null, and post an issue on Github for this. – adeneo Dec 03 '15 at 20:55
  • @adeneo You're right. There is an issue similar to this, but it seems like it will not be altered since it is a breaking change, and lots of people are already using it. – Tholle Dec 03 '15 at 21:02
  • 1
    @Tholle: Well you could always fork the project :-) Going against the nodejs conventions is hard to justify, it only causes problems (such as this). – Bergi Dec 03 '15 at 21:28
  • @Bergi I agree :) I will bug the great guys over at Aerospike some more to maybe include a flag when the client is initialized to comply with the conventions. – Tholle Dec 03 '15 at 21:44
  • 1
    @Tholle: They could just introduce a 2.0 version for the breaking change. Makes more sense than a flag imo. – Bergi Dec 03 '15 at 21:49

1 Answers1

4

Sounds like this is a case for Bluebird's custom promisifier option:

var Promise = require('bluebird');
var aerospike = Promise.promisifyAll(require('aerospike'), {
    promisifier: function(originalFunction, defaultPromisifer) {
        return defaultPromisifer(function() {
            var last = arguments.length-1;
            var callback = arguments[last];
            arguments[last] = function weirdAerospikeCallback(err, rec, meta) {
                if (!err || err.code == status.AEROSPIKE_OK)
                    callback(null, {rec: rec, meta: meta});
                else
                    callback(err);
            };
            originalFunction.apply(this, arguments);
        });
    }
});
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Wow, great! Thanks Bergi! – Tholle Dec 03 '15 at 21:44
  • 2
    You might like to immunise yourself against some future fixed version of Aerospike by testing `if (!err || err.code == aerospike.status.AEROSPIKE_OK)`. Otherwise, one day you/someone may well try out an update and have trouble tracking the cause of a total apparant Aerospike failure. – Roamer-1888 Dec 04 '15 at 11:26
  • @Roamer-1888: Well I'd expect such a breaking change to be clearly described in the release notes of the update; so that you can remove this promisifier completely (maybe use `multiArgs: true`) deliberately. But I see your point, edited. – Bergi Dec 04 '15 at 11:32