Electron集成selenium-webdriver出现UnhandledPromiseRejectionWarning报错
问题分析与解决:Electron中Selenium启动失败报错
报错信息(中文翻译)
(node:3217) 未处理的Promise拒绝警告: Error: spawn /Users/christian/Code/drivers/chromedriver_mac_arm64/chromedriver ENOENT
at /Users/christian/Code/MovieDork/node_modules/selenium-webdriver/remote/index.js:260:24
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
(使用Electron --trace-warnings ...查看警告创建位置)
(node:3217) 未处理的Promise拒绝警告: 未处理的Promise拒绝。该错误要么是因为在没有catch块的async函数中抛出异常,要么是因为拒绝了一个未用.catch()处理的Promise。要在未处理的Promise拒绝时终止node进程,请使用CLI标志--unhandled-rejections=strict。(拒绝ID: 1)
核心问题拆解
- ENOENT错误:系统找不到指定路径下的chromedriver文件,可能是路径错误、文件缺失、权限不足导致。
- 未捕获Promise拒绝:Selenium初始化及后续操作中的Promise未被正确捕获,触发警告。
解决方案
一、修复Chromedriver路径与权限问题
- 验证文件存在性:检查
/Users/christian/Code/drivers/chromedriver_mac_arm64/chromedriver是否真实存在,确认drivers目录结构和代码中的路径匹配。 - 添加可执行权限:在终端执行以下命令,为chromedriver赋予执行权限:
chmod +x /Users/christian/Code/drivers/chromedriver_mac_arm64/chromedriver - 调试路径正确性:在
createWindow函数中添加路径打印,确认生成的路径是否正确:async function createWindow() { const servicePath = // 原路径判断代码 console.log('Chromedriver实际路径:', servicePath); // 后续代码 }
二、捕获Selenium初始化的Promise异常
修改createWindow函数,用try-catch包裹Selenium初始化逻辑,避免未处理的Promise拒绝:
async function createWindow() { try { const servicePath = process.platform == "win32" ? path.join(__dirname, "../drivers/chromedriver.exe") : os.arch() == "x64" ? path.join(__dirname, "../drivers/chromedriver_mac64/chromedriver") : path.join(__dirname, "../drivers/chromedriver_mac_arm64/chromedriver"); console.log('Chromedriver路径:', servicePath); const service = new chrome.ServiceBuilder(servicePath); let options = new chrome.Options(); if (customEnv === "production") options.addArguments("--headless"); driver = await new Builder() .forBrowser(Browser.CHROME) .setChromeService(service) .setChromeOptions(options) .build(); await driver.get("https://www.google.com/ncr"); // 捕获同意按钮查找异常 try { const element = await driver.findElement(By.id("L2AGLb")); await element.click(); } catch (e) { console.log('Google同意按钮不存在:', e); } // 创建窗口逻辑 const mainWindow = new BrowserWindow({ width: 900, height: 600, resizable: true, webPreferences: { preload: path.join(__dirname, "electron/guiExample.js"), contextIsolation: true, nodeIntegration: true, }, }); mainWindow.loadFile(path.join(__dirname, "electron/guiExample.html")); } catch (e) { console.error('Selenium初始化失败:', e); // 可在此添加用户提示逻辑 } }
三、处理窗口关闭时的driver销毁
在window-all-closed事件中,先判断driver是否存在,避免销毁未初始化的driver:
app.on("window-all-closed", async function () { if (driver) { await driver.quit(); } if (process.platform !== "darwin") app.quit(); });
四、其他细节修复
ipcMain.on("execute")中,child变量未声明,改为let child = exec(...)避免全局变量污染:ipcMain.on("execute", (command) => { let child = exec("ls", function (error, stdout, stderr) { if (error !== null) { console.log("exec error: " + error); } }); });- 确保Chrome浏览器版本与chromedriver版本匹配,版本不匹配也会导致启动失败。
内容的提问来源于stack exchange,提问作者christian_js
相关产品推荐
相关产品推荐

