Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
282 views
in Technique[技术] by (71.8m points)

mongodb - Node.js - Mongoose sometimes doesn't save model and throws unclear error

I've got monitoring app which tests multiple instances in parallel and from time to time my model doesn't save and throws kinda weird error from which I don't understand what's wrong.

Let's defined the model first:

const instanceSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
  },
  url: {
    type: String,
    required: true,
    unique: true,
    index: true,
  },
  type: {
    type: String,
    required: true,
  },
  lastSuccessVisit: Date,
  latencies: [Number],
  errorMessage: String,
  lastAlertSent: Date,
  db: {
    lastSuccessVisit: Date,
    lastEventTime: Date,
    lastAlertSent: Date,
  },
  latestError: {
    statusCode: Number,
    name: String,
    data: Object,
  },
});

instanceSchema.statics.findByUrl = function (url) {
  return this.findOne({ url });
};

const Instance = mongoose.model("Instance", instanceSchema);

and now I got this function which takes some instance and update its latencies array:

const updateInstanceLatencies = async (instance, latestTime) => {
  let latencies = Array.isArray(instance.latencies)
    ? [...instance.latencies]
    : [];
  if (latencies.length >= 20) {
    latencies = _drop(latencies);
  }
  latencies.push(latestTime);
  instance.latencies = latencies;
  if (latestTime !== -1) {
    instance.lastSuccessVisit = Date.now();
  }

  try {
    await instance.save();
    return instance;
  } catch (err) {
    logger.log({ level: "info", message: new Date().toISOString() });
    logger.log({ level: "info", message: `Latest time: ${latestTime}` });
    logger.log({ level: "info", message: instance });
    logger.log({ level: "info", message: err });
    return instance;
  }
};

When errors happen, I got following output:

{"level":"info","message":"2021-02-04T16:36:32.007Z"}
{"level":"info","message":"Latest time: 1021"}
{"level":"info","message":{"db":{"lastEventTime":"2021-02-04T16:35:27.312Z","lastSuccessVisit":"2021-02-04T16:35:32.784Z"},"latencies":[1035,1003,992,994,1023,1021],"_id":"601c2162f25a5f001bcd0c6f","name":"ABC","url":"abc.cz","type":"me","__v":5,"lastSuccessVisit":"2021-02-04T16:36:32.005Z"}}
{"level":"info","message":{"version":5,"modifiedPaths":["latencies","lastSuccessVisit"]}}
{"level":"info","message":"2021-02-04T16:36:32.221Z"}
{"level":"info","message":"Latest time: 1236"}
{"level":"info","message":{"db":{"lastEventTime":"2021-02-04T16:35:33.244Z","lastSuccessVisit":"2021-02-04T16:35:33.110Z"},"latencies":[1219,1187,1208,1195,1222,1236],"_id":"601c2162f25a5f001bcd0c6e","name":"CDE","url":"cde.cz","type":"me","__v":5,"lastSuccessVisit":"2021-02-04T16:36:32.218Z"}}
{"level":"info","message":{"version":5,"modifiedPaths":["latencies","lastSuccessVisit"]}}
{"level":"info","message":"2021-02-04T16:36:32.584Z"}
{"level":"info","message":"Latest time: 1593"}
{"level":"info","message":{"latencies":[1550,1403,1356,1456,1461,1593],"_id":"601c2162f25a5f001bcd0c73","name":"EFG","url":"efg.cz","type":"web","__v":5,"lastSuccessVisit":"2021-02-04T16:36:32.582Z"}}
{"level":"info","message":{"version":5,"modifiedPaths":["latencies","lastSuccessVisit"]}}

Anyone knows what could be wrong and how to fix it?

question from:https://stackoverflow.com/questions/66053509/node-js-mongoose-sometimes-doesnt-save-model-and-throws-unclear-error

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The error is unclear because of how you handle it. Your logger, whatever you use, strips out essential parts of the error printing only private fields of the class. It is imperative to have full error in the log including class name and stack trace.

The error you have is the VersionError fired by mongoose to resolve concurrent updates of the same document.

You can read more about revisions here http://aaronheckmann.blogspot.com/2012/06/mongoose-v3-part-1-versioning.html Really sorry for the link but it is where the official documentation sends desperate users.

Essentially the error says there were at least 2 clients, threads, or concurrent jobs within the same event loop that read the same version (5 in your case) of the document and tried to update it. The first update was successful and all following ones fails with this error.

How to handle this error depends on your app - the business logic behind the update. Often it's enough to reload the document and apply the changes to the newer version. In more complex situations you will need to handle this error on the client for the user to review and re-submit the changes. In worst case you may need to use multidocument transactions to roll back changes to the database you made before the conflicting update.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...