Ошибка "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 шт):
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);
}