このコードの実行:
'use strict';
const puppeteer = require('puppeteer');
main().then(() => {
console.log('Done');
});
async function main() {
process.on('unhandledRejection', r => {
console.error(r);
process.exit(1);
});
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.google.com/', {
waitUntil: 'networkidle'
});
await page.waitForSelector('#i-dont-exist', {
timeout: 500
});
}
スタックトレースを生成します:
Error: waiting failed: timeout 500ms exceeded
at Timeout.WaitTask._timeoutTimer.setTimeout (/Users/iftachbar/work/impactlabs/scrapper/node_modules/puppeteer/lib/FrameManager.js:410:58)
at ontimeout (timers.js:488:11)
at tryOnTimeout (timers.js:323:5)
at Timer.listOnTimeout (timers.js:283:5)
これにより、ケースのデバッグが非常に困難になります。
私が期待する直感的な追跡追跡には、 page.waitForSelector()
を実行する行が含まれている必要があります。
多分私が考えていない別の解決策があります...
FWIW、タイムアウトコールバックを設定する親関数もスタックトレースから除外されます。
'use strict';
main();
function main() {
setTimeout(() => { throw new Error('Error in a timeout'); }, 500);
}
Error: Error in a timeout
at Timeout.setTimeout [as _onTimeout] (test.js:6:28)
at ontimeout (timers.js:469:11)
at tryOnTimeout (timers.js:304:5)
at Timer.listOnTimeout (timers.js:264:5)
モンキーパッチで解決しました。 そこにある最善の解決策ではありませんが、大規模なシステムがあり、待機でエラーが発生した場所をデバッグする必要がある場合は必須です。
async function catchTimeoutErrors(callback) {
const error = new Error('Got timeout');
try {
return await callback();
} catch (e) {
if (e.stack.indexOf('Timeout.WaitTask._timeoutTimer.setTimeout') >= 0) {
error.stack += '\nCaused by ' + e.stack;
throw error;
}
throw e;
}
}
async function patchPuppeteer() {
const browser = await puppeteer.launch({
headless: true
});
const page = await browser.newPage();
const mainFrame = page.mainFrame();
const originalWaitForFunction = mainFrame.__proto__.waitForFunction;
mainFrame.__proto__.waitForFunction = function waitForFunction() {
return catchTimeoutErrors(() => originalWaitForFunction.apply(this, arguments));
};
await browser.close();
}
バージョン0.10.1用に作成しましたが、0.11.0ではまだテストしていません。
@barnash puppeteerが非同期であり、スタックトレースが混乱する場所が複数あります。
解決策は、非同期スタックトレースを収集するnode.jsです。 他のすべてのソリューションは、一般的なケースでは十分に機能しません。
最も参考になるコメント
モンキーパッチで解決しました。 そこにある最善の解決策ではありませんが、大規模なシステムがあり、待機でエラーが発生した場所をデバッグする必要がある場合は必須です。
バージョン0.10.1用に作成しましたが、0.11.0ではまだテストしていません。