簡體   English   中英

如何捕獲節點應用程序中的所有錯誤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM