英文:
NodeJS how to handle nested try/catch mechanism
问题
I'm new to Node.js and I'm trying to code two nested try/catch and put retry logic for it. So when inner try/catch catches error I want it to send to outer catch and inside of it I will increase retry count by 1. So when it comes to 5 I will return from while loop. But my problem is that when inner try/catch throws an exception it is not caught by outer one. How can I make sure that it catches the error?
try {
channel.assertQueue(name, { durable: true, arguments: { "x-queue-type": "quorum" } }, async (error, queue) => {
if (error)
throw error;
if (queue) {
try {
channel.sendToQueue(name, Buffer.from(message));
} catch (e) {
console.log(e);
throw e;
}
}
});
} catch (e) {
//retry count will be increased.
throw e.message;
}
英文:
I'm new to Node.js and I'm trying to code two nested try/catch and put retry logic for it. So when inner try/catch catches error I want it to send to outer catch and inside of it I will increase retry count by 1. So when it comes to 5 I will return from while loop. But my problem is that when inner try/catch throws an exception it is not caught by outer one. How can I make sure that it catches the error?
try {
channel.assertQueue(name, { durable: true, arguments: { "x-queue-type": "quorum" } }, async (error, queue) => {
if (error)
throw error;
if (queue) {
try {
channel.sendToQueue(name, Buffer.from(message));
} catch (e) {
console.log(e);
throw e;
}
}
});
} catch (e) {
//retry count will be increased.
throw e.message;
}
答案1
得分: 1
确保外部的catch块捕获内部try/catch块中抛出的错误,您可以按以下方式修改您的代码:
let retryCount = 0;
async function attemptToSendMessage() {
while (retryCount < 5) {
try {
await new Promise((resolve, reject) => {
channel.assertQueue(
name,
{ durable: true, arguments: { "x-queue-type": "quorum" } },
async (error, queue) => {
if (error) {
reject(error); // 如果发生错误,则拒绝承诺
return;
}
if (queue) {
try {
channel.sendToQueue(name, Buffer.from(message));
resolve(); // 如果消息成功发送,则解析承诺
} catch (e) {
reject(e); // 如果在发送消息时发生错误,则拒绝承诺
}
}
}
);
});
break; // 如果消息成功发送,则退出while循环
} catch (e) {
console.log(e);
retryCount++; // 增加重试计数
}
}
if (retryCount === 5) {
throw new Error("在5次尝试后未能发送消息。");
}
}
// 用法
try {
await attemptToSendMessage();
} catch (e) {
// 在此处理错误
console.log(e.message);
}
英文:
To ensure that the outer catch block catches the error thrown in the inner try/catch block, you can modify your code as follows:
let retryCount = 0;
async function attemptToSendMessage() {
while (retryCount < 5) {
try {
await new Promise((resolve, reject) => {
channel.assertQueue(
name,
{ durable: true, arguments: { "x-queue-type": "quorum" } },
async (error, queue) => {
if (error) {
reject(error); // Reject the promise if an error occurs
return;
}
if (queue) {
try {
channel.sendToQueue(name, Buffer.from(message));
resolve(); // Resolve the promise if the message is sent successfully
} catch (e) {
reject(e); // Reject the promise if an error occurs while sending the message
}
}
}
);
});
break; // Exit the while loop if the message is sent successfully
} catch (e) {
console.log(e);
retryCount++; // Increase the retry count
}
}
if (retryCount === 5) {
throw new Error("Failed to send message after 5 attempts.");
}
}
// Usage
try {
await attemptToSendMessage();
} catch (e) {
// Handle the error here
console.log(e.message);
}
答案2
得分: 1
以下是您要翻译的内容:
"你不应该将回调函数传递给 channel.assertQueue
,尤其不是异步的回调函数,而是应该使用 promisify 它。通过 await
,然后可以在外部的 try
/catch
中捕获错误。
你可能正在寻找以下代码:
async function attemptToSendMessage() {
for (let retryCount = 0; retryCount < 5; retryCount++) {
try {
const queue = await new Promise((resolve, reject) => {
channel.assertQueue(
name,
{ durable: true, arguments: { "x-queue-type": "quorum" } },
(error, queue) => {
if (error) reject(error);
else resolve(queue);
}
);
});
if (queue) {
await channel.sendToQueue(name, Buffer.from(message));
}
return; // 如果成功发送消息,则退出循环
} catch (e) {
console.error(e);
}
}
throw new Error("在尝试了5次后仍然无法发送消息。");
}
但是,假设您正在使用 这个 API,您甚至不需要自己将 assertQueue
函数进行 promisify - 如果您不传递回调函数,它已经返回一个 promise。因此,可以进一步简化为:
async function attemptToSendMessage() {
for (let retryCount = 0; retryCount < 5; retryCount++) {
try {
const queue = await channel.assertQueue(
name,
{ durable: true, arguments: { "x-queue-type": "quorum" } }
);
if (queue) {
await channel.sendToQueue(name, Buffer.from(message));
}
return; // 如果成功发送消息,则退出循环
} catch (e) {
console.error(e);
}
}
throw new Error("在尝试了5次后仍然无法发送消息。");
}
希望这对您有所帮助。
英文:
You shouldn't pass a callback to channel.assertQueue
, and not an async
one for certain, instead you should promisify it. With await
, you can then catch the errors in the outer try
/catch
.
You're probably looking for
async function attemptToSendMessage() {
for (let retryCount = 0; retryCount < 5; retryCount++) {
try {
const queue = await new Promise((resolve, reject) => {
channel.assertQueue(
name,
{ durable: true, arguments: { "x-queue-type": "quorum" } },
(error, queue) => {
if (error) reject(error);
else resolve(queue);
}
);
});
if (queue) {
await channel.sendToQueue(name, Buffer.from(message));
}
return; // Exit the loop if the message is sent successfully
} catch (e) {
console.error(e);
}
}
throw new Error("Failed to send message after 5 attempts.");
}
However, assuming you are using this API, you don't even need to promisify the assertQueue
function yourself - it already returns a promise if you don't pass a callback. So simplify further to
async function attemptToSendMessage() {
for (let retryCount = 0; retryCount < 5; retryCount++) {
try {
const queue = await channel.assertQueue(
name,
{ durable: true, arguments: { "x-queue-type": "quorum" } },
);
if (queue) {
await channel.sendToQueue(name, Buffer.from(message));
}
return; // Exit the loop if the message is sent successfully
} catch (e) {
console.error(e);
}
}
throw new Error("Failed to send message after 5 attempts.");
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论