0

I'm using the async library to create a queue.

My code for my queue looks something like this.

const async = require('async');
const db = require('../models');
const logger = require('../logger');
var q = async.queue(async function(task,callback){
    console.log(`added ${task.name} to the master queue`);
    switch (task.name) {
        case 'checkout.session.completed':
            let data = task.data;
            logger.info('checkout.session.completed');
            const stripe_customer_id = data.customer;
            const client_reference_id = data.client_reference_id;
            logger.info(`Stripe Customer ID = ${stripe_customer_id}`);
            logger.info(`Client Reference ID = ${client_reference_id}`);
            try {
                await db.users.update({
                    stripe_customerID:stripe_customer_id
                },{
                    where:{
                        id:client_reference_id
                    }
                })
            } catch (error) {
                logger.error("Failure occured: " + error.message);
                callback(error.message);return;
            }
            callback(null,{
                client_reference_id:client_reference_id,
                stripe_customer_id:stripe_customer_id
            });return;
    
        default:
            break;
    }
    callback("Error: Queue task name not defined.");
},20);
module.exports = q;

What I am trying to do is pass back either the error message or an object containing the client_reference_id or stripe_customer_id.

My code that pushes the task into the queue is this

req.master_q.push({name:event.type,data:data}, function(err,results){
                logger.info(`${event.type} finished...`);
                logger.info("printing results below(success unknown):");
                logger.info(JSON.stringify(results));
                if(err){
                    logger.error();("Error below:");
                    logger.error(err);
                    res.send({
                        status: "Failure",
                        error_message: err
                    });
                }else{
                    logger.info("printing results below(successful queue):");
                    logger.info(JSON.stringify(results));
                    res.send({
                        status: "Success",
                        client_reference_id:results.client_reference_id,
                        stripe_customer_id:results.stripe_customer_id
                    });
                }
            })

For some reason err and results are always empty though. I can tell via console, image below.

enter image description here

Clearly both the error and results are undefined which should be impossible as the callback code clearly only allows the callback to return something one way or the other, and I know it got a client_reference_id correctly since it shows in the console.

My guess is I'm misunderstanding how the library works for passing variables back in the callback but the documentation is lacking information on this and I could not find anything online.

My understanding is the callback first parameter is the error and the second is the data you might want to send back, or the callback has to match the format of whatever callback function you use when creating the task? I'm not sure as it's not clear. Maybe it's neither of these?

In particular this code here should have worked

callback(null,{
         client_reference_id:client_reference_id,
         stripe_customer_id:stripe_customer_id
});return;

My understanding is by sending null for the first argument there is no errors and I can send an object containing what I want to send back in the second parameter, but it doesn't seem to work!

Link to documentation here: https://caolan.github.io/async/v3/docs.html#queue

1 Answer 1

0

The answer is you cannot have async on the definition of the (task,callback) as this will create errors in the way it handles its dynamic generation of the callback.

To work around this you can do something like below, where you create a self calling async function inside the definition.

const async = require('async');
const db = require('../models');
const logger = require('../logger');

var q = async.queue((task,callback) => { //@JA - Putting async on the queue definition function will create errors with callback. DO NOT DO.
    (async () => {
        console.log(`added ${task.name} to the master queue`);
        switch (task.name) {
            case 'checkout.session.completed':
                let data = task.data;
                logger.info('checkout.session.completed');
                const stripe_customer_id = data.customer;
                const client_reference_id = data.client_reference_id;
                logger.info(`Stripe Customer ID = ${stripe_customer_id}`);
                logger.info(`Client Reference ID = ${client_reference_id}`);
                try {
                    await db.users.update({
                        stripe_customerID:stripe_customer_id
                    },{
                        where:{
                            id:client_reference_id
                        }
                    });
                    logger.info("Successfully updated user if it existed");
                } catch (error) {
                    logger.error("Failure occured: " + error.message);
                    callback(error.message,null);return;
                }
                logger.info("Calling success callback below");
                callback(null,{client_reference_id:client_reference_id,stripe_customer_id:stripe_customer_id});return;
            default:
                break;
        }
        callback("Error: Queue task name not defined.",null);;
    })();
},20);

module.exports = q;

Example of using it from push method:

req.master_q.push({name:event.type,data:data}, (err,results) => {
                logger.info(`${event.type} finished...`);
                // logger.info("printing results below(success unknown):");
                // logger.info(JSON.stringify(err));
                if(err){
                    logger.error("Error below:");
                    logger.error(err);
                    res.send({
                        status: "Failure",
                        error_message: err
                    });
                }else{
                    logger.info("printing results below(successful queue):");
                    logger.info(`results=${results}`);
                    logger.info(JSON.stringify(results));
                    res.send({
                        status: "Success",
                        client_reference_id:results.client_reference_id,
                        stripe_customer_id:results.stripe_customer_id
                    });
                }
            })
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.