Nightmare.js catch块截图失败求助:报错提示为读取而非写入文件
解决Nightmare在错误捕获时截图失败的问题
首先,咱们来分析下你代码里的核心问题:
- 嵌套的Nightmare操作链导致状态混乱:你在第一个
.then()里又直接调用nightmare.goto(),这会让同一个Nightmare实例同时处理多条异步操作链,导致实例状态异常,后续的截图操作自然无法正常执行。 - Catch块中的操作方式错误:直接调用
nightmare.screenshot()没有遵循Nightmare的Promise链式调用规则,这种调用方式无法正确触发异步的截图操作,反而可能因为实例处于错误状态,触发了错误的文件操作逻辑(也就是你看到的“尝试读取而非写入”)。 - 未确保截图目录存在:如果
./screenshots目录不存在,Nightmare在尝试写入截图时会抛出错误,这个错误的提示可能会被误解为“读取文件”的问题。
接下来是修改后的完整代码,解决了这些问题:
const Nightmare = require('nightmare'); const fs = require('fs'); const path = require('path'); // 确保截图目录存在,不存在则创建 const screenshotDir = './screenshots'; if (!fs.existsSync(screenshotDir)) { fs.mkdirSync(screenshotDir, { recursive: true }); } const nightmare = Nightmare({ show: true, height: 1080, width: 1920 }); let myVar = 'Non init'; nightmare .goto('http://localhost:8082/myPage1') .wait('.recloc') .screenshot(path.join(screenshotDir, 'tada.png')) .evaluate(() => { return document.querySelector('span.myClass').innerHTML; }) .then((textFound) => { myVar = textFound; console.log('Outer nightmare Success:', textFound); // 继续使用同一个链式操作,而非嵌套调用实例方法 return nightmare .goto('http://localhost:8082/myPage2') .wait('#nav > ul.pull-left.navigation.hidden-xs > li:nth-child(3) > a') .click('Non existing Element ie Error is thrown'); }) .then(() => { console.log('Inner nightmare Success:', myVar); return nightmare.end(); }) .catch((error) => { console.error('Nightmare failed:', error); // 在catch中继续链式调用截图和结束实例,确保异步操作正确执行 return nightmare .screenshot(path.join(screenshotDir, 'error.png')) .end(); });
关键修改点说明:
- 提前创建截图目录:用
fs.mkdirSync确保./screenshots存在,避免因目录缺失导致的写入错误。 - 保持单一链式操作:所有Nightmare的操作都在同一个Promise链中,避免嵌套调用导致的实例状态混乱。
- Catch块中使用链式调用:在捕获错误后,通过
return nightmare.screenshot().end()的方式,让Nightmare正确执行截图的异步操作,然后结束实例。
这样修改后,当错误发生时,就能正常截取当前页面的截图并保存到指定路径了。
内容的提问来源于stack exchange,提问作者Tomas Hesse
相关产品推荐
相关产品推荐

