[英]How to catch all of Errors in node application
我有一個用 node - puppeteer 編寫的應用程序。 我有一個 main 函數,但是這個函數是從另一個函數構建的,實際上,我不知道哪里可能是一個錯誤,所以我想捕獲這個函數中的所有錯誤並重新啟動整個應用程序,但如何才能我這樣做?
示例:我嘗試使用 try...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
(或做其他事情)。
僅供參考,通常不建議像您的原始代碼試圖做的那樣在出現錯誤時立即自動重試(並且就像此代碼遵循該方向一樣)。 通常,您會在下一次重試之前插入一個輕微的延遲,並且您會實現一個重試計數器並在一定次數的嘗試后停止重試。 否則,任何持久性錯誤只會創建一個永遠循環,它可能只會耗盡您所有的 CPU 並且永遠不會停止運行。
要同時實現 retryCntr 和短延遲,您可以這樣做:
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();
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.