如何实现脚本遇错误自动重启及无限循环自动化运行
实现脚本无限循环及错误自动重启方案
需求
脚本需在手动停止前无限循环执行,且遇到任何错误时自动重启流程,无需手动干预。当前脚本正常运行时可持续执行,但报错后需手动重启。
遇到的错误示例
new Error(`${response.errorText} at ${url}`) ^ Error: net::ERR_CONNECTION_CLOSED at https://*********.com at navigate (file:///C:/Users/Omega/Desktop/GOLOGIN/node_modules/puppeteer-core/lib/esm/puppeteer/common/Frame.js:210:23) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Frame.goto (file:///C:/Users/Omega/Desktop/GOLOGIN/node_modules/puppeteer-core/lib/esm/puppeteer/common/Frame.js:180:21) at async CDPPage.goto (file:///C:/Users/Omega/Desktop/GOLOGIN/node_modules/puppeteer-core/lib/esm/puppeteer/common/Page.js:436:16) at async file:///C:/Users/Omega/Desktop/GOLOGIN/create.js:65:3
原代码
import puppeteer from 'puppeteer-core'; import GoLogin from './node_modules/gologin/src/gologin.js'; const delay = ms => new Promise(res => setTimeout(res, ms)); const { connect } = puppeteer; function fingerprint(){ (async () => { const GL = new GoLogin({ token: '********************', }); // Generate Random Profile Username let randomProfile = Math.floor(Math.random()*89999+1000000) // next parameters are required for creating const profile_id = await GL.create({ name: randomProfile, os: 'win', navigator: { language: 'enUS', userAgent: 'random', // get random user agent for selected os resolution: '1920x1080', platform: 'win', }, proxyEnabled: true, proxy: { mode: 'http', host: '********.com', port: '10000', username: '*******', password: '*******', autoProxyRegion: 'us', }, }); console.log('profile id=', profile_id); await GL.update({ id: profile_id, name: randomProfile, }); const profile = await GL.getProfile(profile_id); console.log('new profile name=', profile.name); // Goto site and wait, then delete profile const { status, wsUrl } = await GL.start(); const browser = await connect({ browserWSEndpoint: wsUrl.toString(), ignoreHTTPSErrors: true, }); const page = await browser.newPage(); await page.goto('https://*************.com'); await delay(5000); console.log(await page.content()); await delay(15000); await browser.close(); await GL.stopLocal({ posting: false }); await GL.delete(profile_id); console.log('Success'); })(); }; function run() { setInterval(fingerprint, 25000); }; run();
优化方案及修改后代码
核心修改点
- 全局错误捕获:用
try/catch包裹所有异步操作,捕获执行过程中的所有错误,避免进程崩溃。 - 递归循环代替setInterval:确保前一次任务执行完成(无论成功或失败)后,再启动下一次循环,避免多个任务实例同时运行导致资源泄漏。
- 错误时资源清理:即使发生错误,也确保关闭浏览器、停止GoLogin实例、删除已创建的profile,避免资源浪费。
- 错误后延迟重启:添加短暂延迟,避免报错后立即重启导致的频繁请求问题。
修改后完整代码
import puppeteer from 'puppeteer-core'; import GoLogin from './node_modules/gologin/src/gologin.js'; const delay = ms => new Promise(res => setTimeout(res, ms)); const { connect } = puppeteer; // 定义单次执行逻辑,包含错误处理和资源清理 async function executeTask() { let GL = null; let browser = null; let profile_id = null; try { GL = new GoLogin({ token: '********************', }); // 生成随机profile名称 const randomProfile = Math.floor(Math.random() * 89999 + 1000000); // 创建profile profile_id = await GL.create({ name: randomProfile, os: 'win', navigator: { language: 'enUS', userAgent: 'random', resolution: '1920x1080', platform: 'win', }, proxyEnabled: true, proxy: { mode: 'http', host: '********.com', port: '10000', username: '*******', password: '*******', autoProxyRegion: 'us', }, }); console.log('profile id=', profile_id); // 更新profile(此处原逻辑重复设置名称,可根据需求保留或移除) await GL.update({ id: profile_id, name: randomProfile, }); const profile = await GL.getProfile(profile_id); console.log('new profile name=', profile.name); // 启动profile并连接浏览器 const { wsUrl } = await GL.start(); browser = await connect({ browserWSEndpoint: wsUrl.toString(), ignoreHTTPSErrors: true, }); const page = await browser.newPage(); await page.goto('https://*************.com'); await delay(5000); console.log(await page.content()); await delay(15000); console.log('Task completed successfully'); } catch (error) { console.error('Task failed with error:', error); } finally { // 确保资源被清理,无论成功或失败 try { if (browser) await browser.close(); if (GL) await GL.stopLocal({ posting: false }); if (profile_id) await GL.delete(profile_id); } catch (cleanupError) { console.error('Cleanup failed:', cleanupError); } } } // 递归实现无限循环,每次任务完成后延迟指定时间再启动下一次 async function runLoop(delayMs = 25000) { await executeTask(); console.log(`Waiting ${delayMs}ms before next run...`); await delay(delayMs); // 递归调用自身,实现无限循环 runLoop(delayMs); } // 启动循环 runLoop();
说明
- 脚本会在单次任务执行完成(成功或失败)后,等待25秒再启动下一次任务,可通过修改
runLoop的参数调整延迟时间。 - 所有可能的错误都会被捕获,且资源会被自动清理,避免内存泄漏或残留无效profile。
- 若需要停止脚本,直接在终端按
Ctrl+C即可。
内容的提问来源于stack exchange,提问作者Root X
相关产品推荐
相关产品推荐

