URL Shortener - Passes all tests but throws an error while actually using it

Hello - my URL shortener project passes all of the FCC tests, and I think the code is good (I did a few tests of my own and it worked well initially), for example you can go to https://z-link.glitch.me/2 and it redirects to fcc, as expected.

But then when I try to add a new URL now I get an error in the glitch logs …

The funny thing is though, I ‘console.error’ the error and it seems to be referencing a mongo document which I didn’t create and which I have no reference to in my code… I’m really confused with this one. I’d appreciate any help - thanks in advance if you can help!

My project front end:
https://z-link.glitch.me/

My code/page on glitch:
https://glitch.com/~z-link

Please help - it’s a mystery to me but I could be missing something! Thanks,
Zachary

Update: I’ve tried lots of different things, but I keep getting the same error.
Initially I used a count variable which increased by 1 each time it was assigned to an id field in the database but then I thought that because the app restarts with each edit / when glitch starts up this might be causing the problem, so I replaced this with a random string generator (and tried to implement a check to be sure the generated random string wasn’t already used for an id in the db) but I get the same issue when trying to add new links to the db. I’ve cleared the db of collections (via the mongo atlas gui) but it still won’t work.

This is from the logs -

Node.js listening ...
true
link NOT found in db, adding new link
Error:  { MongoError: E11000 duplicate key error collection: test.links index: short_1 dup key: { short: null }
    at Function.create (/rbd/pnpm-volume/d123e99f-b53a-45f7-b36b-711777fa44bd/node_modules/.registry.npmjs.org/mongodb/3.5.5/node_modules/mongodb/lib/core/error.js:43:12)
    at toError (/rbd/pnpm-volume/d123e99f-b53a-45f7-b36b-711777fa44bd/node_modules/.registry.npmjs.org/mongodb/3.5.5/node_modules/mongodb/lib/utils.js:149:22)
    at coll.s.topology.insert (/rbd/pnpm-volume/d123e99f-b53a-45f7-b36b-711777fa44bd/node_modules/.registry.npmjs.org/mongodb/3.5.5/node_modules/mongodb/lib/operations/common_functions.js:265:39)
    at handler (/rbd/pnpm-volume/d123e99f-b53a-45f7-b36b-711777fa44bd/node_modules/.registry.npmjs.org/mongodb/3.5.5/node_modules/mongodb/lib/core/sdam/topology.js:913:24)
    at fn (/rbd/pnpm-volume/d123e99f-b53a-45f7-b36b-711777fa44bd/node_modules/.registry.npmjs.org/mongodb/3.5.5/node_modules/mongodb/lib/cmap/connection_pool.js:352:13)
    at handleOperationResult (/rbd/pnpm-volume/d123e99f-b53a-45f7-b36b-711777fa44bd/node_modules/.registry.npmjs.org/mongodb/3.5.5/node_modules/mongodb/lib/core/sdam/server.js:487:5)
    at MessageStream.messageHandler (/rbd/pnpm-volume/d123e99f-b53a-45f7-b36b-711777fa44bd/node_modules/.registry.npmjs.org/mongodb/3.5.5/node_modules/mongodb/lib/cmap/connection.js:270:5)
    at MessageStream.emit (events.js:189:13)
    at processIncomingData (/rbd/pnpm-volume/d123e99f-b53a-45f7-b36b-711777fa44bd/node_modules/.registry.npmjs.org/mongodb/3.5.5/node_modules/mongodb/lib/cmap/message_stream.js:144:12)
    at MessageStream._write (/rbd/pnpm-volume/d123e99f-b53a-45f7-b36b-711777fa44bd/node_modules/.registry.npmjs.org/mongodb/3.5.5/node_modules/mongodb/lib/cmap/message_stream.js:42:5)
    at doWrite (_stream_writable.js:410:12)
    at writeOrBuffer (_stream_writable.js:394:5)
    at MessageStream.Writable.write (_stream_writable.js:294:11)
    at TLSSocket.ondata (_stream_readable.js:689:20)
    at TLSSocket.emit (events.js:189:13)
    at addChunk (_stream_readable.js:284:12)
  driver: true,
  name: 'MongoError',
  index: 0,
  code: 11000,
  keyPattern: { short: 1 },
  keyValue: { short: null },
  errmsg:
   'E11000 duplicate key error collection: test.links index: short_1 dup key: { short: null }',
  [Symbol(mongoErrorContextSymbol)]: {} }

So I know that it is error-ing at my link.save expression. :man_shrugging:

And then this is my code:

"use strict";

var express = require("express");
var mongo = require("mongodb");
var mongoose = require("mongoose");

var cors = require("cors");

var app = express();

// Basic Configuration
var port = process.env.PORT || 3000;

// -> this project needs a db !! 💾
mongoose.connect(process.env.DB_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true
});


// Create link schema and include a pre-save which auto increments the count and assigns it to the link _id
const linkSchema = new mongoose.Schema({
  _id: { type: String },
  link: "",
  created_at: ""
});


const Link = mongoose.model("Link", linkSchema);



app.use(cors());

// -> this project needs to parse POST bodies !! 📧
// you should mount the body-parser here
const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: true }));

app.use("/public", express.static(process.cwd() + "/public"));

app.get("/", function(req, res) {
  res.sendFile(process.cwd() + "/views/index.html");
});

// your first API endpoint...
app.get("/api/hello", function(req, res) {
  res.json({ greeting: "hello API" });
});

// -> Functionality 💪
app.post("/api/shorturl/new", (req, res) => {
  // Check getting data & assign to variable
  let data = req.body.url;
  // console.log(data);
  let urlRegex = /^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/;

  //   Attempted to add id check to be sure assigned id is unique - may add when app actually functional
  //   let shortUrlId = makeid();
  //   let uniqueIdTest = false;

  //   while (!uniqueIdTest) {
  //   uniqueIdTest = Link.findOne({ _id: shortUrlId }, (err, doc) => {
  //     if (err) {
  //       console.log('Unique ID -> continue')
  //       return true;
  //     }
  //     if (doc) {
  //       console.log('ID not unique -> assigning new ID')
  //       shortUrlId = makeid();
  //       return shortUrlId;
  //     }
  //   })
  //   };

  // Check if data is a valid URL 🔗 - if not: res.json error object
  console.log(urlRegex.test(data));
  
  if (!urlRegex.test(data)) {
    res.json({ error: "invalid URL" });
  } else {
    Link.findOne({ link: data }, (err, doc) => {
      if (doc) {
        console.log("link found in db");
        res.json({
          original_url: data,
          short_url: doc._id
        });
      } else {
        console.log("link NOT found in db, adding new link");
        let id = makeid();
        //Link.findOne({ _id: id }, (err, doc) => {
          //if(err) {
          let link = new Link({
            _id: id,
            link: data,
            created_at: new Date()
          });
          
          link.save(err, doc => {
            if (err) return console.error("Error: ", err);
            console.log(doc);
            res.json({
              original_url: data,
              short_url: link._id
            });
          });
      }
    });
  }
});

app.get("/:id", (req, res) => {
  let id = req.params.id;
  Link.findOne({ _id: id }, (err, doc) => {
    if (doc) {
      res.redirect(doc.link);
    } else {
      res.redirect("/");
    }
  });
});

app.get("/api/shorturl/new", (req, res) => {
  res.json({ hello: "hi there..." });
});

app.listen(port, function() {
  console.log("Node.js listening ...");
});

// Function for random id ->
function makeid() {
  //makes a random shortened ID
  let randomText = "";
  //make alphanumeric
  let possible =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

  for (let i = 0; i < 5; i++) {
    randomText += possible.charAt(Math.floor(Math.random() * possible.length));
  }
  return randomText;
}

I’ve been stuck on this for a long while now and I’m not sure where I’m going wrong - if anyone can help please do so?

Thanks,
Z