如何捕获节点应用程序中的所有错误



我有一个用node-putpeer编写的应用程序。我有一个主函数,但这个函数是从另一个函数构建的,实际上,我不知道哪里会出现错误,所以我想抓住这个函数中的所有错误,重新启动整个应用程序,但我该怎么做呢?

示例:我试着尝试。。。catch和process.on,但这些方法不起作用:/

const init = async () => {
const { page, browser } = await initPage();
logo();
connectToDb();
await login(page, process.env.USERNAME, process.env.PASSWORD);
await retwitt(page);
process.on('uncaughtException', async () => {
baseLog("Retwiter catched an error, retwiter will be started again.");
await browser.close();
init();
});
};

我想从retwitt((函数或整个应用程序中捕获错误。

const retwitt = async (page) => {
await page.goto(URLwithLangQuery('/home'));
await delay(calcMinsToMs(waitMinsAfterGoToHome));
const twittToShareLink = URLwithLangQuery(await twittSelector(page));
baseLog("Selected twitt to share: ", twittToShareLink);
if (!await wasTwittShared(twittToShareLink)) {
await page.goto(twittToShareLink);
await clickRetwittButton(page);
await confirmRetwitt(page, twittToShareLink);    
await delay(calcMinsToMs(waitMinsAfterRetwitt));
await retwitt(page);
} else {
actionLog("Twitt was already shared.")
await delay(calcMinsToMs(waitMinsAfterSelectingAlreadyRetwittedPost));
await retwitt(page);
}
};

您可以用一个try/catch从多个await语句中捕获拒绝,由于在使用await时拒绝会向上传播,因此您也可以在更高级别捕获它们,如下所示:

const init = async () => {
// let this one throw back to the caller because if you can't initPage()
// there's nothing else to really do here
const { page, browser } = await initPage();     
// catch the rest locally and restart upon error
try {
logo();
connectToDb();
await login(page, process.env.USERNAME, process.env.PASSWORD);
await retwitt(page);
} catch(e) {
console.log(e);
browser.close().then(init, init);
}
};

因此,这将捕获login()retwitt()中的任何拒绝,无论它们在这些函数中发生在哪里(假设它们返回一个在出错时会被拒绝的承诺(。

我选择不从initPage()中捕获错误,因为如果您不能初始化页面,那么实际上就没有其他事情可以做,所以调用者可能应该处理这种情况。如果这是首选行为,您可以在本地捕获它,然后只执行return(或执行其他操作(。


FYI,通常不建议像原始代码试图做的那样,在出现错误时立即自动重试(就像本代码一样,遵循该方向(。通常,您会在下一次重试之前插入一个轻微的延迟,并且您会实现一个重试计数器,并在一定次数的尝试后停止重试。否则,任何持续的错误都会创建一个永远的循环,很可能会耗尽所有的CPU,永远不会停止运行。

要实现重试控制和短延迟,可以这样做:

function delay(t) {
return new Promise(resolve => {
setTimeout(resolve, t);
});
}

const init = async () => {
let maxRetries = 5;
function again() {
return delay(500).then(run);
}

async function run() {
--maxRetries;
if (maxRetries < 0) {
throw new Error("Exceeded max number of retries");
}
// let this one throw back to the caller because if you can't initPage()
// there's nothing else to really do here
const { page, browser } = await initPage();     
// catch the rest locally and restart upon error
try {
logo();
connectToDb();
await login(page, process.env.USERNAME, process.env.PASSWORD);
await retwitt(page);
} catch(e) {
console.log(e);
browser.close().then(again, again);
}
}
return run();
};

相关内容

最新更新