node.jsmongodbmongoosevideo-intelligence-api

mongoose Error: cyclic dependency detected


I wrote a service that analyses videos with Google Cloud Video Intelligence

And I save the analysis results to the MongoDB with mongoose

This is the model I use (I've simplified everything to avoid confusion):

// Video.js

const mongoose = require('mongoose');

const videoSchema = new mongoose.Schema({
    analysis_progress: {
        percent: { type: Number, required: true },
        details: {}
    },
    status: {
        type: String,
        enum: ['idle', 'processing', 'done', 'failed'],
        default: 'idle'
    }
});

module.exports = mongoose.model('Video', videoSchema);

When analyse operation ends, I call the function below and run update like this:


function detectFaces(video, results) {
   //Build query
    let update = {
        $set: {
            'analysis_results.face_annotations': results.faceDetectionAnnotations // results is the the test result
        }
    };

    Video.findOneAndUpdate({ _id: video._id }, update, { new: true }, (err, result) => {
        if (!err)
            return console.log("Succesfully saved faces annotiations:", video._id);
        throw err // This is the line error thrown
    });
}

And this is the error I get:

Error: cyclic dependency detected
    at serializeObject (C:\Users\murat\OneDrive\Masaüstü\bycape\media-analysis-api\node_modules\bson\lib\bson\parser\serializer.js:333:34)
    at serializeInto (C:\Users\murat\OneDrive\Masaüstü\bycape\media-analysis-api\node_modules\bson\lib\bson\parser\serializer.js:947:17)
...

Solutions I tried:

  1. Added {autoIndex: false} inside db config.
mongoose.connect(process.env.DB_CONNECTION, {useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false, autoIndex: false });
  1. Removing retryWrites=true from Mongo URI structure. (I didn't have that parameter in my connection URI already)

So, I think the source of the problem is that I am saving the whole test result but I don't have any other option to do that. I need to save as it is.

I am open to all kinds of suggestions.


Solution

  • Just as I guessed, the problem was that there was a cyclic dependency in the object that came to me from google.

    With help of my colleague:

    Then since JSON.stringify() changes an object into simple types: string, number, array, object, boolean it is not capable of storing references to objects therefor by using stringify and then parse you destroy the information that stringify cannot convert.

    Another way would be knowing which field held the cyclic reference and then unsetting, or deleting that field.

    I couldn't find which field has cycylic dependency so I used I JSON.stringfy() and JSON.parse() to remove it.

    let videoAnnotiations = JSON.stringify(operationResult.annotationResults[0]);
    videoAnnotiations = JSON.parse(videoAnnotiations);