Redirecting an Incorrect Request to a 404 Error Page

I am working on setting up a server that will allow users to access specific valid paths:

 localhost:9090/admin
 localhost:9090/project1 

If a user enters any other invalid paths, they should be redirected to the root and then to the default path localhost:9090/404.html:

How can I achieve this functionality?

Here is my code snippet:

app.js

var express = require('express');
var app = express();
var path = require('path');
var routes = require('c:/monex/routes/index');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use(express.static('c:/monex/admin'));
app.use('/', routes);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
   extended: true
 }));
 app.use(cookieParser());


 var server = app.listen(9090, function () {
 var host = server.address().address
 var port = server.address().port
   console.log("MonexJS  listening at", port)
 })

route.js

 'use strict';
  var express = require('express');
  var app = express();
  var router = express.Router();

  app.engine('html', require('ejs').renderFile);
  app.set('view engine', 'html');

   /* GET home page. */
   router.get('/', function(req, res) {
       res.render('index');
   });

   router.get('/:projectname', function(req, res) {
       var name = req.params.projectname;
       res.render('c:/monex/myprojects/' + name +'/index');
   });


   app.use(function(req, res, next){
        res.status(404).render('c:/monex/404.html', {title: "Sorry, page not found"});
    });

    module.exports = router;

Answer №1

Dealing with errors and routing in Expressjs is quite interesting.

1/ Verifying the Existence of a Project
We utilize the filesystem module to check if a project exists, using the access API. More information on this module can be found at https://nodejs.org/dist/latest-v6.x/docs/api/fs.html

var fs = require('fs') // Check for file existence   
var projectname = 'myfolder';

// Sample code snippet with modifications
router.get('/:projectname', function(req, res) {
   var name = req.params.projectname;
   fs.access(name, fs.constants.F_OK, function(err) {
      if(!err) { // directory exists
         res.render('c:/monex/myprojects/' + name + '/index'); 
         return;
      }
      // Directory does not exist
      next({statusCode: 404});
   })
});

2/ Effectively handling Routing Errors In the code above, whenever a directory does not exist in nodejs, we invoke next with an error object, i.e next(err). There are two types of middlewares in Expressjs - regular and error handling:

app.use("/", function(req, res, next) {})

and

app.use("/", function(err, req, res, next) {})

The key distinction is that the latter is an error handling middleware. Whenever next is called with an argument, Express routes it through error handling middlewares. To address this issue,

You should handle this at the app level to ensure consistent 404 pages across all routers.

In app.js

function Error404(err, req, res, next) {
   if(err.statusCode === "404") {
      res.status(404).render('c:/monex/404.html', {title: "Sorry, page not found"});
   }

   // You can set up other handlers
   if(err.statusCode === "504") {}
}

app.use('/', routes);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
   extended: true
}));
app.use(cookieParser());
app.use(Error404);

REFERENCES
http://expressjs.com/en/guide/error-handling.html

https://github.com/expressjs/express/blob/master/examples/error-pages/index.js

Answer №2

If you want to improve the way your 404 handler function works in Express, you can modify its signature by changing the function parameters to (err, req, res, next). This will allow Express to use it as an error handler and provide a more robust handling of the errors.

Answer №3

I managed to resolve this issue by making a few modifications in my app.js file

app.use(function (err, req, res, next) {
  res.render('c:/monex/505.html', { status: 500, url: req.url });
})

Here is the updated code snippet

var express = require('express');
var app = express();
var path = require('path');
var routes = require('c:/monex/routes/index');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use(express.static('c:/monex/admin'));
app.use('/', routes);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
   extended: true
}));
app.use(cookieParser());

 app.use(function (err, req, res, next) {
  res.render('c:/monex/404.html', { status: 404, url: req.url });
 })


 var server = app.listen(9090, function () {
 var host = server.address().address
 var port = server.address().port
   console.log("MonexJS  listening at", port)
 })

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Adjusting canvas/webgl dimensions to match screen width and height

Hey, I'm currently working on resizing my canvas/webgl to fit the window's height and width at 100%. It works initially, but when I resize the window from small to large, it doesn't scale/fit properly anymore and remains small. Any suggestio ...

Updates to Providers in the latest release of Angular 2

When working with angular 2.0.0-rc.1, we implemented a Provider using the new Provider method as shown in the code snippet below: var constAccessor = new Provider(NG_VALUE_ACCESSOR, { useExisting: forwardRef(() => EJDefaultValueAccessor), ...

Instructions on allowing the user to enter text for searching through an array of objects, and displaying a message if a match is found. Use only pure JavaScript

As a newcomer to JavaScript, I greatly appreciate the support from everyone on this platform. Thank you in advance for your help! I am currently working on building a basic music app as a learning project in JavaScript. The main goal is to understand how J ...

Get the div to occupy the rest of the available height

I am facing a challenge with two divs on my webpage. The bottom one contains content that expands the highest. The page is set to 100% height and width using the CSS property position: absolute. <style> body, html { height:100%, width:100% } ...

Alert users before visiting external websites

Is there a way to notify users about external pages without using popups like in the first example here: https://i.sstatic.net/5QJLu.png Instead of the unwanted code shown above, is there an alternative solution? Is there a different approach that can be ...

Using Node Express to fill out forms with AJAX

Is it possible to update a specific section of a webpage using AJAX without having to refresh the entire page? If so, how can this be achieved correctly? //Get Book router.get('/form/:id', (req, res) => { Book.findOne({ _id: req.params ...

Having trouble getting Angular-UI-Select to work with a basic variable on $scope?

How can you reset an array with selected values so that the values can be reselected from the dropdown? I am working with a people array where the values are initially displayed in a select dropdown. When I choose certain names, they get transferred to th ...

Establishing numerous websocket connections within a singular application

I am looking to conduct load testing on our websocket service. Is there a method to establish multiple websocket connections from one workstation? My attempt with npm ws and websocket modules in conjunction with NodeJS was successful for a single connecti ...

Is there a way to make the checkbox and corresponding text display on a single line within my code snippet?

Bootstrap text-truncate is causing the checkbox and text to appear on separate lines in the following example. How can I adjust it to have the text right after the checkbox? <!DOCTYPE html> <html> <head> <meta charset="UTF-8" / ...

Unable to retrieve HTTP call response during debugging, although it is visible in the browser

When I send an HTTP request to create a record, I am able to see the added record id in the Network section of browsers like Chrome and Firefox. However, when I try to debug the code and retrieve the same id value, I encounter difficulties. I have tried us ...

Issue with triggering ReactJS onClick function accurately

For the function to work correctly, I had to add e.preventDefault(). However, my goal is for it to redirect the user to '/' after submitting the form. Below is the function that I am attempting to trigger: onAddPoints = (e) => { e.prevent ...

Retrieve the output of a JavaScript function and submit it as extra form data

I am working on a JavaScript function that looks like this: <script type="text/javascript"> function doSomething() { var s = 'some data' return s; } </script> and @using (Html.BeginForm(new { data_to_send = ...

The issue of AngularJS directive failing to update controller variable

After conducting an extensive search on both Google and Stack Overflow, I was unable to find a solution to the issue at hand. So, moving forward, here is the problem I am facing: I have created a directive that is intended to retrieve data selected in a ...

Struggling to vertically align elements within iron-pages

Struggling to vertically center the content within iron-pages (nested in a paper-drawer-panel). Check out the code snippet below: <paper-drawer-panel id="drawerPanel" responsive-width="1280px"> <div class="nav" drawer> <!-- Nav Conte ...

I'm curious if it's possible to utilize Raspberry Pi GPIO pins within a JavaScript frontend

Is it possible to utilize Raspberry Pi's GPIO pins in Javascript? Specifically, I am interested in reading the values of the Raspberry Pi PIR sensor without having separate Python and Javascript applications. Ideally, I would like a solution that inte ...

"Using AngularJS to display a blank option as preselected in an ng-option

Having an issue with displaying a preselected value as the selected option in my select element. Check out the code below: <select ng-model="data.company" ng-options="company as company.name for company in companies"></select> $scope.compani ...

The save() function is not triggering the callback on a mongoose schema instance

I am encountering an issue while trying to save a JSON object in my database. The save() function is not triggering, and the JSON object remains unsaved. I suspect there might be a connection problem with Mongoose. Below is the code snippet showcasing the ...

What is the best way to click on a particular button without activating every button on the page?

Struggling to create buttons labeled Add and Remove, as all the other buttons get triggered when I click on one. Here's the code snippet in question: function MyFruits() { const fruitsArray = [ 'banana', 'banana', & ...

Incorrect JavaScript switch case usage

Once again, I find myself with a question regarding JavaScript. This one seems to be an easy fix, but for some reason, I just can't seem to figure out what went wrong: I have a textbox and a button. When the button is clicked, the value should be pas ...

What steps can I take to prompt a ZMQ Router to throw an error when it is occupied?

In my current setup, I have a configuration with REQ -> ROUTER -> [DEALER, DEALER... DEALER]. The REQ acts as a client, the ROUTER serves as a queue, and the DEALER sockets are workers processing data and sending it back to ROUTER for transmission to ...