Uploaded image for project: 'Node.js Driver'
  1. Node.js Driver
  2. NODE-2075

Ensure error events also emit close events in change_stream.js

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 3.3.0
    • Affects Version/s: 3.2.7
    • Component/s: None
    • Labels:
      None

      In `change_stream.js`, we remove all listeners before closing the cursor here: https://github.com/mongodb/node-mongodb-native/blob/next/lib/change_stream.js#L183

      This prevents us from properly using a `close` listener. We can use the following script to see this behavior:

      let stream;
      async function main() {
          const uri = "mongodb://127.0.0.1:26000/";
          const client = new MongoClient(uri, { useNewUrlParser: true });
          
          try {
              await client.connect()
          } catch (err) {
              console.error("failed to connect to MongoDB")
          }
          stream = client.watch([], {
          // let stream = client.db("realm").collection("blogs").watch(watchPipeline, {
              fullDocument: "updateLookup"
          });
      
          stream.on("change", onStreamChangeEvent);
          stream.on("close", onStreamClose);
          stream.on("end", onStreamEnd);
          stream.on("error", onStreamError);
      }
      
      function onStreamChangeEvent(rawEvent: object) {
          console.log(rawEvent);
      };
      
      function onStreamClose() {
          console.warn("MongoDB stream closed.");
      };
      
      function onStreamEnd() {
          console.warn("MongoDB stream ended.");
      };
      
      function onStreamError(err) {
          console.error("MongoDB stream encountered error:");
          console.error(err.stack);
      
          stream.close();
      };
      
      
      main();
      
      console.log("Now watching events.")
      

      To fix this, we can use something along the lines of the following:

      const cursor = this.cursor;
      return cursor.close(err => {
        ['data', 'close', 'end', 'error'].forEach(event => cursor.removeAllListeners(event));
        delete this.cursor;
      
        if (callback) return callback(err);
        return this.promiseLibrary.resolve();
      });
      

            Assignee:
            katherine.walker@mongodb.com Katherine Walker (Inactive)
            Reporter:
            katherine.walker@mongodb.com Katherine Walker (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: