Ошибка You have tried to call .then(), .catch()

Вопрос.

  1. В чём причина проблемы?
  2. Как исправить проблему?

У меня есть проект, я хочу его запустить.
Проект располагается в папке e:\Test\Pro01\.

Я выполнил:

  • открыл консоль Windows;
  • ввёл команду cd e:\Test\Pro01\;
  • ввёл команду node app.js;
  • результат: я получаю сообщение об ошибке;

Использую:

  • Windows-10x64;
  • VSCode;
  • Visual Studio 2022 Community(Установлено NodeJS);
  • Node.js (c:\Program Files\nodejs\node.exe);
  • Wampserver64;
  • MySql;

Сообщение об ошибке
e:\Test\Pro01>node app.js
Start at http://localhost:3000
You have tried to call .then(), .catch(), or invoked await on the result of query that is not a promise,
which is a programming error.
Try calling con.promise().query(), or require(‘mysql2/promise’) instead of ‘mysql2’
for a promise-compatible version of the query interface. T
o learn how to use async/await
or Promises check out documentation
at mysql2 - npm,
or the mysql2 documentation at …/Promise-Wrapper.md
e:\Test\Pro01\node_modules\mysql2\lib\commands\query.js:41
throw new Error(err);
^

Error: You have tried to call .then(), .catch(), or invoked await on the result of query that is not a promise, which is a programming error. Try calling con.promise().query(), or require(‘mysql2/promise’) instead of ‘mysql2’ for a promise-compatible version of the query interface. To learn how to use async/await or Promises check out documentation at …/mysql2#using-promise-wrapper, or the mysql2 documentation at ./documentation/Promise-Wrapper.md
at Query.then (e:\Test\Pro01\node_modules\mysql2\lib\commands\query.js:41:11)
at MySQLStore.query (e:\Test\Pro01\node_modules\express-mysql-session\index.js:392:12)
at MySQLStore. (e:\Test\Pro01\node_modules\express-mysql-session\index.js:110:9)
at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read_file_context:68:3)

Node.js v18.7.0

e:\Test\Pro01>

Обновление-1
app.js

const express = require("express");
const bodyParser = require("body-parser");
const flash = require("connect-flash");
const expressSession = require("express-session");
const MySQLStore = require("express-mysql-session")(expressSession);
const connection = require("./db/connection");
const helpers = require("./helpers");
const config = require("./config.json");
const moment = require("moment");
const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;
const crypto = require("crypto");
const cookieParser = require("cookie-parser");

moment.locale("ru");

const app = express();

let listener = require("http").Server(app);

passport.serializeUser(function (user, done) {
  done(null, user.id);
});

passport.deserializeUser(function (id, done) {
  connection.query("select * from users where id = " + id, (err, rows) => {
    done(err, rows[0]);
  });
});

passport.use(
  "local-signup",
  new LocalStrategy(
    {
      usernameField: "email",
      passwordField: "password",
      passReqToCallback: true,
    },
    (req, email, password, done) => {
      connection.query(
        "select * from users where email = ?",
        [email],
        (err, rows) => {
          if (err) {
            return done(err);
          }
          if (rows.length) {
            return done(
              null,
              false,
              req.flash("signupMessage", "That email is already taken.")
            );
          } else {
            // create the user

            crypto.pbkdf2(
              password,
              email,
              25000,
              512,
              "sha256",
              (err, hash) => {
                let newUserMysql = new Object();
                newUserMysql.email = email;
                newUserMysql.password = hash.toString("hex");

                connection.query(
                  "INSERT INTO users (email, password) values (?, ?)",
                  [newUserMysql.email, newUserMysql.password],
                  (err, rows) => {
                    newUserMysql.id = rows.insertId;
                    return done(null, newUserMysql);
                  }
                );
              }
            );
          }
        }
      );
    }
  )
);

passport.use(
  "local-login",
  new LocalStrategy(
    {
      usernameField: "email",
      passwordField: "password",
      passReqToCallback: true,
    },
    (req, email, password, done) => {
      connection.query(
        "SELECT * FROM `users` WHERE `email` = ?",
        [email],
        (err, rows) => {
          if (err) {
            return done(err);
          }
          if (!rows.length) {
            return done(
              null,
              false,
              req.flash("loginMessage", "No user found.")
            );
          }

          crypto.pbkdf2(password, email, 25000, 512, "sha256", (err, hash) => {
            password = hash.toString("hex");
            if (!(rows[0].password == password)) {
              return done(
                null,
                false,
                req.flash("loginMessage", "Oops! Wrong password.")
              );
            }
          });

          return done(null, rows[0]);
        }
      );
    }
  )
);

const routes = require("./routes.js")(express.Router(), passport);

app
  .use(
    express.static("static", {
      maxage: "4h",
    })
  )
  .use(cookieParser())
  /*.use(i18n.init)*/
  .set("view engine", "ejs")
  .use(bodyParser.json())
  .use(
    bodyParser.urlencoded({
      extended: true,
    })
  )
  .use(
    expressSession({
      secret: config.express.secret,
      store: new MySQLStore({}, connection),
      resave: false,
      saveUninitialized: false,
    })
  )
  .use(passport.initialize())
  .use(flash())
  .use(passport.session())
  .use(async (req, res, next) => {
    res.locals.error = null;
    res.locals.helpers = helpers;
    res.locals.user = null;
    res.locals.moment = moment;
    res.locals.url = req.url;
    next();
  })
  .use(routes)
  .use((req, res, next) => {
    let err = new Error("Здесь ничего нет");
    err.status = 404;
    next(err);
  })
  .use((err, req, res, next) => {
    if (err.status != 404) {
      err.message = "Неизвестная ошибка";
    }

    return res.status(err.status || 500).render("error", {
      message: err.message,
      error: req.app.get("env") === "development" ? err : null,
      status: err.status || 500,
    });
  });

let server = listener.listen(config.express.port || 3000, () => {
  const host =
    server.address().address == "::" ? "localhost" : server.address().address;
  const port = server.address().port;
  console.log("Start at http://%s:%s", host, port);
});

Обновление-2
…\controllers\main.js

const db = require('../db');
const fs = require('fs');
const path = require('path');
const config = require('../config.js');
class Main {

  async video(req, res, next) {
    const videoFolder = './static/video'
    let videos = []

    fs.readdirSync(videoFolder).forEach((file) => {
      let extension = path.extname(file)
      let filename = path.basename(file, extension)

      videos.push({
        file,
        filename: parseInt(filename),
      })
    })

    videos = videos.sort((a, b) => {
      return a.filename - b.filename
    })



    return res.render('video', {
      domain: config.express.domain,
      videos,
    })
  }

    async panomuseum(req, res) {
    const article = await db.article.getByID(req.params.lang);
    const sub = await db.article.getRoot(req.params.lang);
    const files = await db.files.getByOwnerId(req.params.lang);

    const lang = await db.lang.getById(req.params.lang);

    return res.render('panomuseum', {
      article,
      sub,
      files,
      lang
    });
  }

  async panomuseum2(req, res) {
    const article = await db.article.getByID(req.params.lang);
    const sub = await db.article.getRoot(req.params.lang);
    const files = await db.files.getByOwnerId(req.params.lang);

    const lang = await db.lang.getById(req.params.lang);

    return res.render('panomuseum2', {
      article,
      sub,
      files,
      lang
    });
  }

  async panotheatre(req, res) {
    const article = await db.article.getByID(req.params.lang);
    const sub = await db.article.getRoot(req.params.lang);
    const files = await db.files.getByOwnerId(req.params.lang);

    const lang = await db.lang.getById(req.params.lang);

    return res.render('panotheatre', {
      article,
      sub,
      files,
      lang
    });
  }

  async index(req, res) {
    const article = await db.article.getByID(req.params.lang);
    const sub = await db.article.getRoot(req.params.lang);
    const files = await db.files.getByOwnerId(req.params.lang);


    const lang = await db.lang.getById(req.params.lang);
    const timeout = await db.settings.getByID("timeout");
    const caption = await db.settings.getByID("caption");


    return res.render("index", {
      article,
      sub,
      files,
      lang,
      timeout,
      caption,
      domain: req.app.get("domain"),
    });
  }

  async menu(req, res) {
    return res.render("menu", {
      domain: req.app.get("domain"),
    });
  }

  async slideshow(req, res) {
    const slideshow = await db.files.getSlideshow();
    const timer = await db.settings.getByID("timer");

    return res.render("slideshow", {
      slideshow,
      timer,
      domain: req.app.get("domain"),
    });
  }

  async slide(req, res) {
    const slideshow = await db.files.getByID(req.params.id);
    const timer = await db.settings.getByID("timer");

    return res.render("slideshow", {
      slideshow: [slideshow],
      timer,
      domain: req.app.get("domain"),
    });
  }

  async article(req, res) {
    const article = await db.article.getByID(req.params.id);
    const sub = await db.article.getSub(req.params.id);
    const files = await db.files.getByOwnerId(req.params.id);
    const id = req.params.id;
    const lang = await db.lang.getById(req.params.lang);
    const timeout = await db.settings.getByID("timeout");
    const caption = await db.settings.getByID("caption");

    return res.render("index", {
      id,
      article,
      sub,
      files,
      lang,
      timeout,
      caption,
      domain: req.app.get("domain"),
    });
  }

  
  async lang(req, res) {
    const langs = await db.lang.getAll();

    let activeCount = 0;

    for (let lang of langs) {
      if (lang.value == 1) {
        activeCount++;
      }
    }

    if (activeCount == 0) {
      return res.redirect("/0");
    } else if (activeCount == 1) {
      for (let lang of langs) {
        if (lang.value == 1) {
          return res.redirect("/" + lang.id);
        }
      }
    }

    const timeout = await db.settings.getByID("timeout");

    return res.render("lang", {
      langs,
      timeout,
    });
  }

  async openSlide(req, res) {
    console.log("openSlide");
    let files = await db.files.getSyncSmartHome();

    parentIO.sockets.in("client").emit("goToUrl", {
      message: "/slide/" + files[parseInt(req.params.id)].id,
    });

    return res.json({
      success: true,
    });
  }

  async openSlideshow(req, res) {
    console.log("open slideshow");

    parentIO.sockets.in("client").emit("goToUrl", {
      message: "/slideshow",
    });

    return res.json({
      success: true,
    });
  }
}

module.exports = new Main();

Сообщение говорит


You have tried to call .then(), .catch(), or invoked await on the result of query that is not a promise,

Что в общем и целом описывает возможную проблему. Очень сложно сказать что именно пошло не так, не видя кода. Что внутри самого app.js?

1 симпатия

См. Обновление-1.

Я только разбираюсь с NODE JS/
Буду признателен за любую помощь…

Владею на начальном уровне C#(ASP.NET(MVC))

Обновление-1
Искать по всему коду где используется .then(), .catch() и разбираться?

Обновление-2
См. вопрос Обновление-2

Не, это вряд ли. Сообщение об ошибке упоминает mysql2, возможно проблема там, где ты подключаешь базу (возможно ./db/connection ?)
Проблема появилась после какого-то изменения в коде? Попробуй откатить до того момента, пока проблема не исчезнет, это даст понять, что именно пошло не так.

1 симпатия

\db\connection.js

const mysql = require('mysql2');
const config = require('../config.json');
const connection = mysql.createConnection({
  host: config.mysql.host,
  user: config.mysql.user,
  password: config.mysql.password,
  database: config.mysql.db,
  charset: 'utf8_general_ci',
  multipleStatements: true
});

connection.connect();

module.exports = connection;

Не знаю…
Дали проект, сказали разобраться…
Что он нерабочий никто не говорил, но то, что рабочий тоже внятно никто не сказал…

Ситуация интересная в целом что-то нестандартная. Я не уверен в результате, но ради интереса попробуй строку const mysql = require('mysql2'); заменить на const mysql = require('mysql2/promise');. Что это меняет в выводе?

И приложи содержимое package.json чтобы понимать какие библиотеки используются и какой версии

1 симпатия