0

We are using seneca.js to put messages into a queue in our Node app. We promisified the act call, and wrapped all the seneca use in a service we called MessageBus. So now, MessageBus.publish uses Seneca to put the call on a queue and wait for a response:

MessageBus.publish({ ... })
    .then(result => doSomething(result))
    .catch(error => handleError(error));

Here's the relevant part of the service that we wrote:

function MessageBus() {
    //initialization
    seneca.use('seneca-amqp-transport'); //instruct seneca to use a transport

    seneca.client({});
    seneca.listen({});

    const act = function(message, cb) {
        seneca.act(message, function(err, response) {
            if (err) {
                console.error(err);
                cb(err);
            } else {
                cb(null, response);
            }
        });
    };

    const promisified = Promise.promisify(act, { context: seneca });

    return {
        publish: promisified,
    };
}

module.exports = MessageBus();

On every call, we needed to add the catch to handle errors. That worked pretty well, but had a lot of repeated code.

Now, we're using async/await, and I'd like to handle the errors all in one spot and not need to wrap every call in a try/catch block. My attempts, though, didn't work.

What I added was a function that called the promisified function and caught the errors. Then publish exported that function instead. It half worked, but in the act function, cb was not defined. No matter what I tried, cb was never defined and never called.

I know it looks like errors are handled in the seneca.act, but the express app will still crash if an error occurs and the MessageBus.publish isn't wrapped in a try/catch block.

My goal was to have something along the lines of Wes Bos's solution in this catchErrors function. I'd love to not have to wrap every MessageBus.publish call in a try/catch block, but instead write that code in one spot and have all the errors handled there.

Roamer-1888
  • 19,138
  • 5
  • 33
  • 44
pjlamb12
  • 2,300
  • 2
  • 32
  • 64
  • The thing about try/catch is that exceptions propagate upwards anyway - so you can just handle them at a higher level of your program. – Benjamin Gruenbaum Apr 11 '18 at 21:23
  • Could you add the express route handler as well so we can get a better overview of what you're trying to do? We're all programmers here, so code usually explains better than words. One thing I've noticed is the `const act = ...` function isn't required, you could just do `Promise.promisify(seneca.act, { context: seneca })`. Also, what's the actual error your program crashes with? – Sven Apr 11 '18 at 21:28
  • The app is a Sails.js app, which is built on express. And if I don't catch the errors, then it's actually Seneca that crashes and requires the app to be restarted. And I know the above code could be changed to be promisified like you mentioned, but we actually do a little bit of other stuff in that act function that I didn't put in because it was irrelevant to the question. – pjlamb12 Apr 12 '18 at 05:58
  • If there was no *other stuff* in that act function, then you could write `'publish': Promise.promisify(seneca.act, { 'context': seneca }),`. In composing an answer taking *other stuff* into account, one would need to know whether that stuff was to be executed synchronously (before calling `senena.act()`) or asynchronously after `senena.act()` responds - (or a bit of each). – Roamer-1888 Apr 12 '18 at 21:07
  • Either way, you shouldn't be promisifying your own `act()` function. That misnderstanding is what's giving you an issue with `cb`. – Roamer-1888 Apr 12 '18 at 21:16

0 Answers0