gpt4 book ai didi

javascript - 我在node.js中使用promise的错误在哪里

转载 作者:行者123 更新时间:2023-12-02 21:16:36 24 4
gpt4 key购买 nike

我对 Node.js 还很陌生。在我当前的测试项目中,我想发送确认电子邮件或其他电子邮件,具体取决于加载的模板。模板存储在MySQL中。

我得到的结果是:

{
"message": {
"error": {},
"foo": "bar"
}
}

所以错误位是空的,我不知道为什么......如果我在代码中的不同点手动拒绝,它工作得很好,所以问题不在于中间件、路由器或 server.js 文件。

此外,我还拒绝了“Foo: Bar”,以检查哪个 catch block 捕获了错误。

这是我的 mailer.js 文件:

const nodemailer = require('nodemailer');

let conDB;

module.exports = (injectedMySql) => {
conDB = injectedMySql
return {
sendMail: sendMail
}
}

const sendMail = (mail) => {
return new Promise((resolve,reject) => {
loadTemplate(mail.templateId, mail.languageId)
.then(data => {
const mailserver = {
host: "something.com",
port: 465,
secure: true, // use TLS
auth: {
user: "something@something.com",
pass: "PASSWORD"
},
tls: {
// do not fail on invalid certs
rejectUnauthorized: false
}
};
const body = {
from: 'something@something.com',
to: mail.toAdress,
subject: allReplace(data.subject, mail.subjectReplace),
text: allReplace(data.body, mail.textReplace),
html: allReplace(data.html, mail.htmlReplace)
}

// create a nodemailer transporter using smtp
let transporter = nodemailer.createTransport(mailserver)

transporter.sendMail(body)
.then(data => {console.log(data)
resolve(data)
})
.catch(err => {reject("sendMail problem")})
})
.catch(error => {reject({"error": error, "foo": "bar"})})
})
}

function allReplace (str, obj) {
var retStr = str;
for (var x in obj) {
retStr = retStr.replace(new RegExp(x, 'g'), obj[x]);
}
return retStr;
};

const loadTemplate = (mailTemplate, languageId) => {
return new Promise((resolve,reject) => {
if(mailTemplate === null || languageId === null)
reject("nop, something is missing");
else
{
if (typeof conDB.query === "function")
{
conDB.query('SELECT * FROM email_template WHERE language_id = ? AND template_id = ?', [mailTemplate,languageId])
.then(data => {resolve(data)})
.catch(err => {reject("mysql has a problem")})
}
else
{
reject("function is not available");
}
}
})
}

这是我的 mysql.js 文件:

var mysql = require('mysql2/promise');

const databaseConfigs = {
host: 'localhost',
user: 'USERNAME',
password: 'PASSWORD',
database: 'DBNAME'
};
const createID = table => {
return new Promise((resolve,reject) => {
//execute the query to register the user
let query = '';
let id = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
query = `SELECT * FROM ${table} WHERE id = ?`
this.query(query,[table,id])
.then(data => {
console.log(data[0].length)
if(data[0].length==0)
{
resolve(id)
}
else
{
createID(table)
.then(data => {resolve(data)})
.catch(error => {reject(error)})
}
})
.catch(error => {reject(error)})
})
}

async function query (sql,att) {

let connection = await mysql.createConnection(databaseConfigs);
return new Promise( ( resolve, reject ) => {
console.log(`Query: '${sql}'`);
connection.query(sql,att)
.then(data => {resolve(data)})
.catch(error => {reject(error)})
connection.end();
});
}

async function transaction(queries, queryValues) {
if (queries.length !== queryValues.length) {
return Promise.reject(
'Number of provided queries did not match the number of provided query values arrays'
)
}
const connection = await mysql.createConnection(databaseConfigs)
try {
await connection.beginTransaction()
const queryPromises = []

queries.forEach((query, index) => {
queryPromises.push(connection.query(query, queryValues[index]))
})
const results = await Promise.all(queryPromises)
await connection.commit()
await connection.end()
return results
} catch (err) {
await connection.rollback()
await connection.end()
return Promise.reject(err)
}
}

module.exports.transaction = transaction;
module.exports.query = query;
module.exports.createID = createID;

谢谢大家!

克里斯

最佳答案

我稍微清理了你的代码。特别是错误处理,因为您总是用 Promise.reject("message") 掩盖错误。

我认为让您感到困惑的是您已经在使用与 Promise 一起使用的库(您不需要再次将它们包装到 Promise 中)。这非常好,因为您可以使用 async/await 。

希望对您有帮助。如果有不清楚的地方,请询问。

const nodemailer = require('nodemailer');

let conDB;

module.exports = (injectedMySql) => {
conDB = injectedMySql
return {
sendMail: sendMail
}
}

// your load template function already uses promises no need to wrap it
const sendMail = async mail => {
const data = await loadTemplate(mail.templateId, mail.languageId)

const mailserver = {
host: "something.com",
port: 465,
secure: true, // use TLS
auth: {
user: "something@something.com",
pass: "PASSWORD"
},
tls: {
// do not fail on invalid certs
rejectUnauthorized: false
}
};
const body = {
from: 'something@something.com',
to: mail.toAdress,
subject: allReplace(data.subject, mail.subjectReplace),
text: allReplace(data.body, mail.textReplace),
html: allReplace(data.html, mail.htmlReplace)
}

// create a nodemailer transporter using smtp
let transporter = nodemailer.createTransport(mailserver)
try {
// Return the value of sendmail
return await transporter.sendMail(body);
} catch (err) {
// handle error or throw it. I'll throw as you rejected the Promise here it.
// this part will actually help you as you now can see the correct error instead of your rejected "foo bar" erro object
throw err;
}
}

function allReplace(str, obj) {
var retStr = str;
for (var x in obj) {
retStr = retStr.replace(new RegExp(x, 'g'), obj[x]);
}
return retStr;
};

const loadTemplate = async (mailTemplate, languageId) => {
if (mailTemplate === null || languageId === null)
throw new Error("nop, something is missing");
else {
if (typeof conDB.query === "function") {
try {
const data = await conDB.query('SELECT * FROM email_template WHERE language_id = ? AND template_id = ?', [mailTemplate, languageId]);
} catch (err) {
// it's better to use the real error you always hide the real reason why something went wrong with your promise reject :).
throw err;
}
}
else {
throw new error("function is not available");
}
}
}

.

var mysql = require('mysql2/promise');

const databaseConfigs = {
host: 'localhost',
user: 'USERNAME',
password: 'PASSWORD',
database: 'DBNAME'
};

const createID = async table => {
// use GUID? https://www.npmjs.com/package/guid
let id = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
let query = `SELECT * FROM ${table} WHERE id = ?`
try {
data = await this.query(query, [table, id]);
} catch (error) {
// as we throw the error in query we got to catch it here
// handle it or throw it (I throw it because I can't handle it ;).)
throw error;
}
console.log(data[0].length)
if (data[0].length == 0) {
return id;
} else {
return await createID(table);
}
}

const query = async (sql, att) => {
let connection = await mysql.createConnection(databaseConfigs);
console.log(`Query: '${sql}'`);
try {
const data = await connection.query(sql, att);
return data;
} catch (error) {
// Handle error or throw it again
// you rejected the promise so i throw it here
throw error;
} finally {
connection.end();
}
}

// I changed it to make it the same as the other functions from this
// async function transaction(queries, queryValues) { to
const transaction = async (queries, queryValues) => {
if (queries.length !== queryValues.length) {
// just throw an error
throw new Error('Number of provided queries did not match the number of provided query values arrays');
}
const connection = await mysql.createConnection(databaseConfigs)
try {
await connection.beginTransaction()
const queryPromises = []

queries.forEach((query, index) => {
queryPromises.push(connection.query(query, queryValues[index]))
})
const results = await Promise.all(queryPromises)
await connection.commit()
await connection.end()
return results
} catch (err) {
await connection.rollback()
await connection.end()
// this is not needed
// return Promise.reject(err)
// if you don't want to handle it here just throw the error
throw err;
}
}

module.exports.transaction = transaction;
module.exports.query = query;
module.exports.createID = createID;

关于javascript - 我在node.js中使用promise的错误在哪里,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60950152/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com