javascriptnode.jsexpressmodel-view-controllerpug

Express using default error handling page instead of view?


I'm following this MDN Express tutorial on creating a "Local Library" app, that uses Pug (Jade) as its templating engine. In this part of the tutorial, it details creating a controller for handling a form POST request for a "create genre" page.

exports.genre_create_get = (req, res, next) => {
  res.render("genre_form", { title: "Create Genre" });
};

// Handle Genre create on POST.
exports.genre_create_post = [
  // Validate and sanitize the name field.
  body("name", "Genre name must contain at least 3 characters")
    .trim()
    .isLength({ mid: 3 })
    .escape(),

  // Process request after validation and sanitization.
  asyncHandler(async (req, res, next) => {
    // Extract the validation errors from a request.
    const errors = validationResult(req);

    // Create a genre object with escaped and trimmed data.
    const genre = new Genre({ name: req.body.name });

    if (!errors.isEmpty()) {
      // There are errors. Render the form again with sanitized values/error messages.
      res.render("genre_form", {
        title: "Create Genre",
        genre: genre,
        errors: errors.array(),
      });

      return;
    } else {
      // Data from form is valid.
      // Check if Genre with same name already exists.
      const genreExists = await Genre.findOne({ name: req.body.name })
        .collation({ locale: "en", strength: 2 })
        .exec();
      if (genreExists) {
        // Genre exists, redirect to its detail page.
        res.redirect(genreExists.url);
      } else {
        await genre.save();
        // New genre saved. Redirect to genre detail page.
        res.redirect(genre.url);
      }
    }
  }),
];

Here is the view that it corresponds to:

extends layout

block content

  h1 #{title}

  form(method="POST")
    div.form-group
      label(for="name") Genre:
      input#name.form-control(type="text", placeholder="Fantasy, Poetry etc." name="name" required value=(undefined===genre ? "" : genre.name) )
    button.btn.btn-primary(type="submit") Submit

  if errors
    ul
      for error in errors
        li!= error.msg

Looking at the bottom of the tutorial, it shows you what is supposed to happen when the user tries to send an invalid form: it should create a list element that appears below the form field detailing the error. However, here's what happens when I try to reproduce the error in my own localhost:enter image description here

For some reason, Express seems to be taking over the error handling and generating it's own error page. Does anyone know how to fix this issue?

I compared my controller and template code with the finished repo's code, and it seems to be exactly the same.


Solution

  • You have a typo in body validator, so body validator doesn't run, and genre.save() fails mongoose schema validation:

      body("name", "Genre name must contain at least 3 characters")
        .trim()
        .isLength({ mid: 3 })
        .escape(),
    

    isLength should be min instead of mid:

    .isLength({ min: 3 })