Dns.lookup always throws null error // URL shortener microservice project

hi all, I am working on the URL shortener microservice project, however, it always throws null error as follows:

app.post('/api/shorturl/new',function(req,res){
  const REPLACE_REGEX = /^https?:\/\//i;
  var lookupurl = req.body.url;
  //var removeprotocal = lookupurl.replace(REPLACE_REGEX,'');
  var urlObject = new URL(lookupurl);
  let isValid = false;
  console.log("lookupurl",lookupurl);
  // When options.all is true, the result will be an Array.
  var options = {
    family: 6,
    hints: dns.ADDRCONFIG | dns.V4MAPPED
  };

  //options.all = true;
  //dns.lookup(urlObject.hostname, options, function(err, address, family) {
  dns.lookup(urlObject.hostname, function(err, address, family) {
    //if (err) res.json({ "error": "invalid URL" });
    console.log("err",err);
    if (err != null) isValid = true;
  });
  console.log("isValid",isValid);
  if (isValid) {
    var urlno = shortId.generate;
    Shorturl.create({original_url: lookupurl, short_url: urlno});
    res.json({ "original_url": lookupurl, "short_url": urlno });
  } else {
    res.json({ "error": "invalid URL" });
  }
});

from the log:

lookupurl https://www.freecodecamp.org
isValid false
err null

Whats wrong with my code here? Any help would be highly appreciated.

Hello there,

Are you sure you are passing the correct first argument to dns.loopup? I did not use new URL to construct mineā€¦

here my full code:

'use strict';

var express = require('express');
var mongo = require('mongodb');
var mongoose = require('mongoose');
var dns = require('dns');
var shortId = require('shortid');
var bodyParser = require('body-parser');

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
});

var Schema = mongoose.Schema;
var shorturlSchema = new Schema({
  original_url: String,
  short_url: Number
});

var Shorturl  = mongoose.model('Shorturl',shorturlSchema);

app.use(cors());

/** this project needs to parse POST bodies **/
// you should mount the body-parser here
app.use(bodyParser.urlencoded({ extended: false }));
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'});
});


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


app.post('/api/shorturl/new',function(req,res){
  const REPLACE_REGEX = /^https?:\/\//i;
  var lookupurl = req.body.url;
  //var removeprotocal = lookupurl.replace(REPLACE_REGEX,'');
  var urlObject = new URL(lookupurl);
  let isValid = false;
  console.log("lookupurl",lookupurl);
  // When options.all is true, the result will be an Array.
  var options = {
    family: 6,
    hints: dns.ADDRCONFIG | dns.V4MAPPED
  };

  //options.all = true;
  //dns.lookup(urlObject.hostname, options, function(err, address, family) {
  dns.lookup(urlObject.hostname, function(err, address, family) {
    //if (err) res.json({ "error": "invalid URL" });
    console.log("err",err);
    if (err != null || err != '') isValid = true;
  });
  console.log("isValid",isValid);
  if (isValid) {
    var urlno = shortId.generate;
    Shorturl.create({original_url: lookupurl, short_url: urlno});
    res.json({ "original_url": lookupurl, "short_url": urlno });
  } else {
    res.json({ "error": "invalid URL" });
  }
});

app.get('/:shorturl', function(req,res){
  var shortUrl = Shorturl.findOne({short_url:req.params.url_string});
  if (shortUrl == null) return res.sendStatus(404);
  res.redirect(shortUrl.original_url);
});

And the first argument is correct for dns.loopup

What I mean to clarify is:

  • The first argument should be: www.freecodecamp.org, when the input is https://www.freecodecamp.org
  • I suspect your issue is with this:
if (err != null || err != '') isValid = true;

It should be if (err === null) { isValid = true; }. If there is not an error, it is valid, yes?

Also, I suspect you will have issues with the dns.lookup function being asynchronous. You should probably handle your db logic within the function.

Thanks! I fixed the issue and passed the test.