Sunday, 4 June 2017

Writing to MongoDB fails silently during Neo4j session.run() but works fine normally

The problem is that everything works fine in isolation, but as soon as I combine the Log.create(obj) into the Neo4j result stream, it stops working and what I assume is some Promise behaviour is eating all log information so I can't figure out why exactly it's not working or how to force it to display meaningful information.

I have been trying to diagnose this for the past 2 days, but I can't figure out why.

I have 2 files: example.js and E1Logger/index.js

The logger file is simply the schema and models for a method that writes an object to MongoDB. It works fine if I comment out the bottom half of example.js.

I've tried probably like 20 different combinations of chaining promises, catching, done, exec, making it more asynchronous, making it more synchronous, and I can't seem to get any meaningful information.

I'm dying to know what is required to make it work.

example.js

 //var config = require('./config');
 const mongoose = require('mongoose');
 mongoose.connect('mongodb://localhost:27017/major', error => { if (error) { console.error('ERROR: ' + error) }});
 //mongoose.Promise = global.Promise;

 var neo4j = require('neo4j-driver').v1;
 var config = {};
 config.neo4jHost = 'bolt://localhost:7687';
 config.neo4jUser = 'neo4j';
 config.neo4jPassword = 'garbagepassword';
 var driver = neo4j.driver(config.neo4jHost, neo4j.auth.basic(config.neo4jUser, config.neo4jPassword));

 var E1Logger = require('./E1Logger');

 let newInfoLog = {
     logType: 'INFO',
     eventType: 'Purge Stale Invite',
     result: 'Success',
     invitedByUser: {
         neo4jNodeID: 123,
         name: 123 + ' ' + 321,
         email: 123
     },
     purgedUser: {
         neo4jNodeID: 123,
         email: 123
     },
     createdAt: 123,
     expirationAt: 123
 };

 let newErrorLog = {
     logType: 'ERROR',
     eventType: 'Purge Stale Invite',
     result: 'Fail',
     reason: 123,
     attemptedQuery: 123,
 };

 E1Logger.info(newInfoLog);

 E1Logger.error(newErrorLog);

 // Calculate cutoff time for expired invites and form the Cypher Query
 var currentTime = new Date().getTime();
 var sliceTime = currentTime - 604800000; // 604800000 milliseconds in one week
 var cypherQuery = 'MATCH (e:Person)-[r:INVITED_TO_APP]->(x) WHERE r.expirationAt<=\'' + sliceTime + '\' AND r.status=\'pending\' RETURN id(e) as invitedByUserId, e.given_name as invitedByUserFirstName, e.family_name as invitedByUserLastName, e.email as invitedByUserEmail, r.createdAt as createdAt, r.expirationAt as expirationAt, id(x) as purgedUserId, x.email as purgedUserEmail';

 // Execute Purge Event
 var session = driver.session();
 session
     .run(cypherQuery)
     .then(function(result){
         result.records.forEach(function(record) {
             // Generate log for each expired invite
             let newInfoLog = {
                 logType: 'INFO',
                 eventType: 'Purge Stale Invite',
                 result: 'Success',
                 invitedByUser: {
                     neo4jNodeID: record.get('invitedByUserId').low,
                     name: record.get('invitedByUserFirstName') + ' ' + record.get('invitedByUserLastName'),
                     email: record.get('invitedByUserEmail')
                 },
                 purgedUser: {
                     neo4jNodeID: record.get('purgedUserId').low,
                     email: record.get('purgedUserEmail')
                 },
                 createdAt: record.get('createdAt'),
                 expirationAt: record.get('expirationAt')
             };
             // Log result
             console.log('PURGED: ' + JSON.stringify(newInfoLog));
             E1Logger.info(newInfoLog);
         });
         session.close();
         driver.close();
     })
     .catch(function(error) {
         // Generate log for failed purge
         let newErrorLog = {
             logType: 'ERROR',
             eventType: 'Purge Stale Invite',
             result: 'Fail',
             reason: error,
             attemptedQuery: cypherQuery,
         };

         // Log result
         console.log('ERROR: ' + JSON.stringify(newErrorLog));
         E1Logger.error(newErrorLog);
         //session.close();
         //driver.close();
     });

 mongoose.disconnect();

E1Logger/index.js

 const mongoose = require('mongoose');

 // Define Info Log Schema
 const InfoLogModel = mongoose.model('Infolog', new mongoose.Schema({
     logType: String,
     loggedAt: { type: Number, default: new Date().getTime() },
     eventType: String,
     result: String,
     invitedByUser: {
         neo4jNodeID: Number,
         name: String,
         email: String
     },
     purgedUser: {
         neo4jNodeID: Number,
         email: String
     },
     createdAt: Number,
     expirationAt: Number
 }));

 // Define Error Log Schema
 const ErrorLogModel = mongoose.model('Errorlog', new mongoose.Schema({
     logType: String,
     loggedAt: { type: Number, default: new Date().getTime() },
     eventType: String,
     result: String,
     reason: String,
     attemptedQuery: String,
 }));


 module.exports = {
     // Define Info Log Model
     info: function(eventData) {
         InfoLogModel.create(eventData, (error, addedEvent) => {
             if (error) throw error;
             console.log('INFO: ' + addedEvent);
         });
     },
     // Define Error Log Model
     error: function(eventData) {
         ErrorLogModel.create(eventData, (error, addedEvent) => {
             if (error) throw error;
             console.log('ERROR: ' + addedEvent);
         });
     }
 };

I suspect the problem is at ErrorLogModel.create(eventData). I've never been able to get it to write to MongoDB from inside session.run(). A had a couple combinations that were showing something about a promise rejection, but that's as close as I got. I recall something like ErrorLogModel.create(eventData).catch( err => console.log('ok') ); made it do that.

Am I missing something about promises here? Why does running working code through Neo4j session.run().then() cause it to stop working? Is it maybe a bug I should report to Mongoose or Neo4j?



via agm1984

No comments:

Post a Comment