3

I am using puppeteer to build a small app to automatically fill forms online. I am using Gmail as an example to test the functionality without clicking the submit button.

I open the Gmail URL and locate the username input field by using a function called findInputFieldByName. The code works fine, webpage opens and I can see puppeteer printing [email protected] in the username field.

The code is:

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='[email protected]';
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);
    }

})();

As you can see the code is looking for an input field whose name is identifier in the returned HTML. However, if I were to use a different name such as identifier1, which is not on the Gmail Login page, I want the code to throw a custom error message saying "Input field name identifier1 not found" and the code should stop.

If I change

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

to

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

I get the following error:

main program error:TypeError: Cannot read property 'type' of null

I understand that this is because the function findInputFieldByName has not failed. It just returned a null object because there is no input field with the name identifier1. The code actually failed when it tried to type the email address.

However, my question is how can I throw an error from within the findInputFieldByName function so that it stops the at the const userNameElement = await findInputFieldByName.. execution?

I have tried to use promises within the findInputFiledByName function as:

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));
    }
});
}

but I am getting the following message:

main program error:TypeError: Cannot read property 'catch' of undefined (node:12332) UnhandledPromiseRejectionWarning: Error: Could not find input name identifier1

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

at new Promise (< anonymous >)

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

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

at < anonymous >

at process._tickCallback (internal/process/next_tick.js:188:7) (node:12332) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) (node:12332) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

How should I handle the custom errors? I am new to Javascript to any help is much appreciated.enter code here

1 Answer 1

3

First of all, return the promise instead of assigning it to a variable.

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

After that, you can throw error if need.

await findInputFieldByName(page,'identifier').catch(error => {
    throw ('The following error occurred: ' + error) // <-- pass the error to main program
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.