skip to Main Content

I’ve been trying to fix this for a while now. The problem is actually when I send a post request via the fetch api and then catch it with the post request in the node js file it should normally render the error page but it doesn’t. How does this happen?

ps: don’t mind the text. I am dutch.

node js file:

const express = require("express");
const { emailFormSchema } = require("./schemas.js");
const rateLimiter = require("express-rate-limit");
if (process.env.NODE_ENV !== "production") {
    require("dotenv").config();
}
const bodyParser = require("body-parser");
const app = express();
const path = require("path");
const ExpressError = require("./utils/ExpressError");
const ejsMate = require("ejs-mate");
const nodemailer = require("nodemailer");
const Swal = require("sweetalert2");
const { Console } = require("console");

// Setting up ejs and the stylesheets
app.engine("ejs", ejsMate);
app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "/views"));
app.use(express.static(path.join(__dirname, "public")));
// app.use(bodyParser.urlencoded({ extended: true }));

app.use(express.json());


// POST route for form
app.use(express.json());

app.post("/contact", limiter, validateForm, (req, res, next) => {
    const transporter = nodemailer.createTransport({
        service: "gmail",
        auth: {
            user: process.env.email,
            pass: process.env.pass,
        },
    });
    const mailOptions = {
        From: req.body.email,
        // to moet nog aangepast worden naar mamas email
        to: process.env.email,
        subject: `Nieuw bericht van ${req.body.email}`,
        text: `naam: ${req.body.name},
bericht: ${req.body.message}`,
    };

    transporter.sendMail(mailOptions, (error, info) => {
        if (error) {
            console.log(error);
            res.send("error token");
        } else {
            console.log(`mail verzonden: ${info.response}`);
            res.send("success");
        }
    });
});

// HOME
app.get("/", (req, res) => {
    res.render("./pages/home.ejs");
});

let message = "";

app.post("/error", (req, res, next) => {
    const msg = req.body.message;
    message = req.body.message;
    console.log("error message is:", msg);

    // res.redirect("/error");
    res.redirect("/error");
});

app.get("/error", (req, res, next) => {
    if (message) {
        console.log("hitted");
        res.render("./pages/error", { message });
        // next(new ExpressError(message, 404));
    } else {
        next(new ExpressError("Pagina niet gevonden", 404));
    }
});

app.all("*", (req, res, next) => {
    next(new ExpressError("Pagina niet gevonden", 404));
});

app.use((err, req, res, next) => {
    const { statusCode = 500, message } = err;
    console.log("Message in error handeler is:", message);

    res.render("./pages/error", { message, statusCode });
});

app.listen(3000, () => {
    console.log("Listening on port 3000");
});

2

Answers


  1. Because post requesy is not for rendering page.
    Post request is for data transfers. Like rest api. You should use res.

    So you should use res.write instead of res.render.

    Or sending GET request for rendering.

    P.S. I’m very sorry for my terrible english skill.

    Login or Signup to reply.
  2. I understand you have a /contact endpoint and that you want to redirect the user to an /error page where you display some information when something goes wrong?

    Basically you need to:

    1. Write a custom express middleware error handler.
    2. There you need to redirect the user to your dedicated error route AND pass the error using a query parameter.
    3. serve a nice error page at the /error route

    That would look something like this:

    const express = require("express");
        const { emailFormSchema } = require("./schemas.js");
        const rateLimiter = require("express-rate-limit");
        if (process.env.NODE_ENV !== "production") {
            require("dotenv").config();
        }
        const bodyParser = require("body-parser");
        const app = express();
        const path = require("path");
        const ExpressError = require("./utils/ExpressError");
        const ejsMate = require("ejs-mate");
        const nodemailer = require("nodemailer");
        const Swal = require("sweetalert2");
        const { Console } = require("console");
    
        // Setting up ejs and the stylesheets
        app.engine("ejs", ejsMate);
        app.set("view engine", "ejs");
        app.set("views", path.join(__dirname, "/views"));
        app.use(express.static(path.join(__dirname, "public")));
        // app.use(bodyParser.urlencoded({ extended: true }));
    
        app.use(express.json());
    
    
        // POST route for form
        app.use(express.json());
    
        app.post("/contact", limiter, validateForm, (req, res, next) => {
        const transporter = nodemailer.createTransport({
        service: "gmail",
        auth: {
            user: process.env.email,
            pass: process.env.pass,
            },
        });
        const mailOptions = {
            From: req.body.email,
            // to moet nog aangepast worden naar mamas email
            to: process.env.email,
            subject: `Nieuw bericht van ${req.body.email}`,
            text: `naam: ${req.body.name},
            bericht: ${req.body.message}`,
            };
    
            transporter.sendMail(mailOptions, (error, info) => {
            if (error) {
                console.log(error);        
                next(error)    // handle the error in the middleware
                } else {
                console.log(`mail verzonden: ${info.response}`);
                res.send("success");
                }
                });
            });
    
            // error endpoint
            app.get('/error', (req, res, next) => {
            const errorMessage = req.query.errorMessage;
            // here you can serve a nice error page with extra info
            res.status(500).send(`An error occurred: ${errorMessage}`);
            })
            // HOME
            app.get("/", (req, res) => {
                res.render("./pages/home.ejs");
            });
    
            const errorHandler = (err, req, res, next) => {
            console.log('err!!', err)
    
            // Redirect the user to the /error endpoint with the error information
            const errorMessage = encodeURIComponent(err.message);
            res.redirect(`/error?errorMessage=${errorMessage}`);
            }
            app.use(errorHandler)
    
            app.listen(3000, () => {
                console.log("Listening on port 3000");
            });

    Note: keep in mind the order:

    • Custom error handlers need to go AFTER the regular routes
    • The more specific routes need to go BEFORE the more generic routes

    Hope this helps | hopelijk komen mams haar mailtjes aan 😉

    Note: keep in consideration that this is a bit oldschool. You can also go next(error) without writing a custom error handler where you redirect to a error page. Express has default error handlers and this will just result in a 500 at the client-side. There you can let the user know the problem by displaying a toaster message.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search