Puppeteer:在异步函数中使用 await 调用的 javascript 函数中抛出自定义错误消息



我正在使用puppeteer构建一个小应用程序来自动在线填写表格。我以Gmail为例,无需单击提交按钮即可测试功能。

我打开 Gmail URL 并使用名为findInputFieldByName的函数找到用户名输入字段。代码工作正常,网页打开,我可以在用户名字段中看到木偶打印test@gmail.com

代码为:

const puppeteer = require('puppeteer');
const gmailUrl='https://accounts.google.com/signin/v2/identifier?continue=https%3A%2F%2Fmail.google.com%2Fmail%2F&service=mail&sacu=1&rip=1&flowName=GlifWebSignIn&flowEntry=ServiceLogin';
const userName='test@gmail.com';
const findInputFieldByName = (page,inputName) => {
return page.$('input[name="'+inputName+'"]');
}
(async () => {
try {
const Browser = await puppeteer.launch({headless:false,
defaultViewport:{width:600,height:800}
});
const page=await Browser.newPage();
page.on('load', () => console.log('Page loaded ' + page.url()));
await page.goto(gmailUrl);
const userNameElement = await findInputFieldByName(page,'identifier').catch(error => {
console.log('The following error occurred: ' + error);
});
await userNameElement.type(userName,{delay:50});
} catch(e) {console.log('main program error:' + e);
}
})();

如您所见,代码正在查找一个输入字段,其名称在返回的 HTML 中identifier。但是,如果我使用不同的名称,例如标识符 1,该名称不在 Gmail 登录页面上,我希望代码抛出一条自定义错误消息,指出">找不到输入字段名称标识符 1",并且代码应该停止。

如果我改变

const userNameElement = await findInputFieldByName(page,'identifier').catch(error => {
console.log('The following error occurred: ' + error);
});

const userNameElement = await findInputFieldByName(page,'identifier1').catch(error => {
console.log('The following error occurred: ' + error);
});

我收到以下错误:

主程序错误:类型错误:无法读取 null 的属性"type">

我知道这是因为函数findInputFieldByName没有失败。它只是返回了一个空对象,因为没有名称标识符 1的输入字段。代码在尝试键入电子邮件地址时实际上失败了。

但是,我的问题是我如何从findInputFieldByName函数中抛出错误,以便它在const userNameElement = await findInputFieldByName..执行时停止?

我尝试在findInputFiledByName函数中使用承诺,如下所示:

const findInputFieldByName = (page,inputName) => {
let promise=new Promise(function (resolve,reject){
var elm= page.$('input[name="'+inputName+'"]');
if (elm.length>0) {
resolve(elm);
} else {
reject(Error('Could not find input name ' + inputName));
}
});
}

但我收到以下消息:

主程序错误:类型错误:无法读取未定义的属性"catch" (节点:12332(未处理的承诺拒绝警告:错误:找不到输入名称标识符1

at C:\Users\test1.js:11:10

在新的承诺(<匿名>(

at findInputFieldByName (C:\Users\test1.js:6:14(

at C:\Users\test1.js:26:32

在<匿名>

at process._tickCallback (内部/进程/next_tick.js:188:7( (节点:12332( 未处理的承诺拒绝警告:未处理的承诺 拒绝。此错误起源于异步 没有 catch 块的函数,或者拒绝承诺 不使用 .catch(( 处理。(拒绝 ID: 1( (节点:12332( [DEP0018] 弃用警告:不推荐使用未处理的承诺拒绝。在 未来,未处理的承诺拒绝将终止 节点.js具有非零退出代码的进程。

我应该如何处理自定义错误?我是Javascript的新手,非常感谢任何帮助。enter code here

首先,返回 promise 而不是将其分配给变量。

const findInputFieldByName = (page, inputName) => {
return new Promise(((resolve, reject) => { // <-- Return it

之后,如果需要,您可以throw错误。

await findInputFieldByName(page,'identifier').catch(error => {
throw ('The following error occurred: ' + error) // <-- pass the error to main program
});

最新更新