Ошибка "Encoding not recognized: 'undefined' (searched as: 'undefined')" Node.js MySQL

На сервере онлайн хостинга создаю пул подключений и выполняю до 5-ти execute, на последних запросах к базе данных часто (но не всегда) возникает такая ошибка, вот записанный лог:

07.04, 18:51: "test, labReport, exec5: removeQuest", Error: Encoding not recognized: 'undefined' (searched as: 'undefined') at PromisePool.execute (/home/login/domains/site/public_html/myapp/node_modules/mysql2/lib/promise/pool.js:54:22) at savingDataAll (/home/login/domains/site/public_html/myapp/app.js:886:30) at reportQuest (/home/login/domains/site/public_html/myapp/app.js:499:17) at processTicksAndRejections (internal/process/task_queues.js:95:5)

Код следующий:

const mysql = require('mysql2')
function createPoolDB(limit){ 
    const pool = mysql.createPool({
        connectionLimit: `${limit}`,
        host: "localhost",
        user: "login",
        database: "login",
        password: "password"
    }).promise()
    return pool;
}   


app.post('/removeNowProgress', (request, response) => {
        let date = getDate() // получает текущие дату и время
            let session = request.sessionID
            let nameTable = users[session].user + '_progress'
            const DB = createConnectDB()
            const pool = createPoolDB(0)
            users[session].exec.labReport = {
                reward: `UPDATE users_stage2 SET ResPoints = ResPoints + ${changeRP}, pokecoins = pokecoins + ${pokecoins} WHERE nickname = '${users[session].user}'`,
                quest: `UPDATE ${nameTable} SET p6 = 'fullWait', rem = '${resultQuest}', streak = '${newStreak}' WHERE target = 'quest'`,
                timer: `UPDATE ${nameTable} SET p1 = ${nowTime}, p2 = ${timerSec} WHERE target = 'timer'`,
                removeAll: `UPDATE ${nameTable} SET p1 = DEFAULT, p2 = DEFAULT, p3 = DEFAULT, p4 = DEFAULT, p5 = DEFAULT, p6 = DEFAULT WHERE target = 'pokemons' || target = 'lvl' || target = 'place'`,
                removeQuest: `UPDATE ${nameTable} SET p1 = DEFAULT, p2 = DEFAULT, p3 = DEFAULT, p4 = DEFAULT, p5 = DEFAULT WHERE target = 'quest'`,
            }
    savingDataAll(session, pool, date, users[session].exec.labReport, 'reward', 'quest', 'timer', 'removeAll', 'removeQuest')
                    .then(result=>{response.json(timerSec)})
        })
    
    function savingDataAll(session, DB, date, obj, exec1, exec2, exec3, exec4, exec5){ // сам закрывает соединение с БД
        let nameObj = ''
        for(let key in users[session].exec){
            if(users[session].exec[key] == obj){nameObj = key}
        }
        return Promise.all([
            // 0
            ...(obj[exec1] ? [DB.execute(obj[exec1])
                .then(result => {obj[exec1] = null; saveErrLog(DB.pool._closed, date, 'lab-exec1', 'test')})
                .catch(err => {saveErrLog(err, date, `${users[session].user}, ${nameObj}, exec1: ${exec1}`, 'errorLogDB')})
            ] : [null]),
            // 1
            ...(obj[exec2] ? [DB.execute(obj[exec2])
                .then(result => {obj[exec2] = null; saveErrLog(DB.pool._closed, date, 'lab-exec2', 'test')})
                .catch(err => {saveErrLog(err, date, `${users[session].user}, ${nameObj}, exec2: ${exec2}`, 'errorLogDB')})
            ] : [null]),
            // 2
            ...(obj[exec3] ? [DB.execute(obj[exec3])
                .then(result2 => {obj[exec3] = null; saveErrLog(DB.pool._closed, date, 'lab-exec3', 'test')})
                .catch(err => {saveErrLog(err, date, `${users[session].user}, ${nameObj}, exec3: ${exec3}`, 'errorLogDB')}),
            ] : [null]),
            // 3
            ...(obj[exec4] ? [DB.execute(obj[exec4])
                .then(result2 => {obj[exec4] = null; saveErrLog(DB.pool._closed, date, 'lab-exec4', 'test')})
                .catch(err => {saveErrLog(DB.pool._closed, date, 'lab-catch-exec4', 'test'); saveErrLog(err, date, `${users[session].user}, ${nameObj}, exec4: ${exec4}`, 'errorLogDB')})
            ] : [null]),
            ...(obj[exec5] ? [DB.execute(obj[exec5])
                .then(result2 => {obj[exec5] = null; saveErrLog(DB.pool._closed, date, 'lab-exec5', 'test')})
                .catch(err => {saveErrLog(DB.pool._closed, date, 'lab-catch-exec5', 'test'); saveErrLog(err, date, `${users[session].user}, ${nameObj}, exec5: ${exec5}`, 'errorLogDB')})
            ] : [null])
        ])
        .finally(() => {
            saveErrLog(DB.pool._closed, date, 'lab-before-DB.end', 'test')
            DB.end()
            .then(()=>{saveErrLog(DB.pool._closed, date, 'lab-after-DB.end', 'test'); 
        })
})

Помогите пожалуйста с ответом, буду благодарен! Подскажите в чём может быть проблема, я самоучка и очень не хватает знания основ(


Ответы (1 шт):

Автор решения: Airat Galiullin

connectionLimit: 0 — это некорректное значение, так как пул не сможет создать ни одного соединения.

const pool = createPoolDB(5)

Это позволит одновременно выполнять до 5 запросов.

Сейчас соединения закрываются слишком рано. Лучше создать пул соединений один раз (глобально), а не для каждого запроса. Создание пула на каждый запрос ведёт к серьёзным проблемам с производительностью и ошибкам соединений.

// Создай пул соединений один раз, при старте сервера:
const pool = mysql.createPool({
    connectionLimit: 10,  // например, 10 одновременных соединений
    host: "localhost",
    user: "login",
    database: "login",
    password: "password"
}).promise();

// Используй один и тот же пул соединений во всех запросах.

Затем используй его так:

app.post('/removeNowProgress', (request, response) => {
    let date = getDate();
    let session = request.sessionID;
    let nameTable = users[session].user + '_progress';

    users[session].exec.labReport = {
        reward: `UPDATE users_stage2 SET ResPoints = ResPoints + ${changeRP}, pokecoins = pokecoins + ${pokecoins} WHERE nickname = '${users[session].user}'`,
        quest: `UPDATE ${nameTable} SET p6 = 'fullWait', rem = '${resultQuest}', streak = '${newStreak}' WHERE target = 'quest'`,
        timer: `UPDATE ${nameTable} SET p1 = ${nowTime}, p2 = ${timerSec} WHERE target = 'timer'`,
        removeAll: `UPDATE ${nameTable} SET p1 = DEFAULT, p2 = DEFAULT, p3 = DEFAULT, p4 = DEFAULT, p5 = DEFAULT, p6 = DEFAULT WHERE target IN ('pokemons', 'lvl', 'place')`,
        removeQuest: `UPDATE ${nameTable} SET p1 = DEFAULT, p2 = DEFAULT, p3 = DEFAULT, p4 = DEFAULT, p5 = DEFAULT WHERE target = 'quest'`,
    }

    savingDataAll(session, pool, date, users[session].exec.labReport, 'reward', 'quest', 'timer', 'removeAll', 'removeQuest')
        .then(result => {
            response.json(timerSec);
        })
        .catch(err => {
            saveErrLog(err, date, "removeNowProgress", "errorLogDB");
            response.status(500).send("Ошибка сервера");
        });
});

Теперь функция запроса (без закрытия пула!):

function savingDataAll(session, DB, date, obj, exec1, exec2, exec3, exec4, exec5) {
    let promises = [];

    [exec1, exec2, exec3, exec4, exec5].forEach((execKey, index) => {
        if (obj[execKey]) {
            promises.push(
                DB.execute(obj[execKey])
                    .then(() => {
                        obj[execKey] = null;
                    })
                    .catch(err => {
                        saveErrLog(err, date, `${users[session].user}, exec${index + 1}: ${execKey}`, 'errorLogDB');
                    })
            );
        }
    });

    return Promise.all(promises);
}
→ Ссылка