Start a new topic
Answered

CollectionHooks and modues.logger bug?

Found out something really strange. I write following into a preSaveHook


 var collectionAccess = modules.collectionAccess;

var myID = collectionAccess.objectID(request.entityId);

var ads = collectionAccess.collection("ads");

var logger = modules.logger;

logger.info(request); 

  ads.findOne({"_id": myID}....


It all works well if i leave it like this. but as soon as i remove logging info the request.enttityId returns empty string and it breaks everything i trying to do later on. I'm missing something or what?


Best Answer

Hi Jelian,


When removing the logger.info(), you would not be able to inspect the request object and that is why I believe you assume the request.enttityId is returning empty string. Looking at the code snippet, I believe the issue is not in the logger.info() but rather that in the pre-save hook the response.continue() is being called right after the if clause, which will be executed without waiting for the asynchronous findOne() callback and thus, the 

request.body.views = result.views; 

will never be executed:


function onPreSave(request, response, modules) {
    if (request.method === 'POST') {
        if (!request.body.hasOwnProperty('username')) {
            request.body.views = 0;
        }
    } else if (request.method === 'PUT') {
        var collectionAccess = modules.collectionAccess;
        var myID = collectionAccess.objectID(request.entityId);
        var ads = collectionAccess.collection("ads");
        var logger = modules.logger;
        logger.info(request);

        ads.findOne({ "_id": myID }, [], function(err, result) {
            if (err) {
                response.error(err);
            }
            // Will never be executed
            request.body.views = result.views;
            response.continue();
        });
    }

    // This is sinhronous and will be executed right after the "if" clause (will not wait for the findOne asynchronous callback)
    response.continue();
}


As the pre-save hook request methods options are only two (POST and PUT), you can change the code like this:


function onPreSave(request, response, modules) {
    if (request.method === 'POST') {
        if (!request.body.hasOwnProperty('username')) {
            request.body.views = 0;
        }
        // Continue with the exeuction of the request
        response.continue();
    } else {
        var collectionAccess = modules.collectionAccess;
        var myID = collectionAccess.objectID(request.entityId);
        var ads = collectionAccess.collection("ads");

        ads.findOne({ "_id": myID }, [], function(err, result) {
          // Will wait for the callback and then continue with the execution of the request
            if (err) {
                response.error(err);
            }
            request.body.views = result.views;
            response.continue();
        });
    }
}


Let me know if this has solved the issue. 

If the issue persists, could you please describe what error you are receiving?


Regards

Martin Apostolov


Hi Martin,


Yes what you described was exactly the culprit. It all works as expected now. I have a lot to learn yet, but this was a valuable lesson for sure.

Thanks a lot for helping me!


Regads

Jelian Radoev

Answer

Hi Jelian,


When removing the logger.info(), you would not be able to inspect the request object and that is why I believe you assume the request.enttityId is returning empty string. Looking at the code snippet, I believe the issue is not in the logger.info() but rather that in the pre-save hook the response.continue() is being called right after the if clause, which will be executed without waiting for the asynchronous findOne() callback and thus, the 

request.body.views = result.views; 

will never be executed:


function onPreSave(request, response, modules) {
    if (request.method === 'POST') {
        if (!request.body.hasOwnProperty('username')) {
            request.body.views = 0;
        }
    } else if (request.method === 'PUT') {
        var collectionAccess = modules.collectionAccess;
        var myID = collectionAccess.objectID(request.entityId);
        var ads = collectionAccess.collection("ads");
        var logger = modules.logger;
        logger.info(request);

        ads.findOne({ "_id": myID }, [], function(err, result) {
            if (err) {
                response.error(err);
            }
            // Will never be executed
            request.body.views = result.views;
            response.continue();
        });
    }

    // This is sinhronous and will be executed right after the "if" clause (will not wait for the findOne asynchronous callback)
    response.continue();
}


As the pre-save hook request methods options are only two (POST and PUT), you can change the code like this:


function onPreSave(request, response, modules) {
    if (request.method === 'POST') {
        if (!request.body.hasOwnProperty('username')) {
            request.body.views = 0;
        }
        // Continue with the exeuction of the request
        response.continue();
    } else {
        var collectionAccess = modules.collectionAccess;
        var myID = collectionAccess.objectID(request.entityId);
        var ads = collectionAccess.collection("ads");

        ads.findOne({ "_id": myID }, [], function(err, result) {
          // Will wait for the callback and then continue with the execution of the request
            if (err) {
                response.error(err);
            }
            request.body.views = result.views;
            response.continue();
        });
    }
}


Let me know if this has solved the issue. 

If the issue persists, could you please describe what error you are receiving?


Regards

Martin Apostolov


1 person likes this

Hi Martin,


Here is the hook code https://pastebin.com/yZCpVPD3

AppKey: kid_ByZoedtqf

Hi Jelian,


I tried followed the steps that you have listed but could not reproduce the described behavior. 

Could you please send the whole hook code and your App Key ( kid_............ ) in order to review the server logs?


Regards

Martin Apostolov

Login or Signup to post a comment