0

I am running a script with Kameleo and I keep getting this error:

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(). To terminate the node process on unhandled promise rejection

This is my code:

const { KameleoLocalApiClient, BuilderForCreateProfile } = require('@kameleo/local-api-client');
const puppeteer = require("puppeteer");
(async () => {
    const client = new KameleoLocalApiClient();
    const baseProfiles = await client.searchBaseProfiles({
        deviceType: 'desktop',
        browserProduct: 'chrome'
    });

    // Create a new profile with recommended settings
    // for browser fingerprinting protection
    const requestBody = BuilderForCreateProfile
        .forBaseProfile(baseProfiles[0].id)
        .setRecommendedDefaults()
        .build();
    const profile = await client.createProfile({ body: requestBody });

    // Start the browser
    await client.startProfile(profile.id);

    const browserWSEndpoint = `ws://localhost:5050/puppeteer/$(profile.id)`;
    const browser = await puppeteer.connect({browserWSEndpoint, defaultViewport: null});
    const page = await browser.newPage();
    await page.goto("https://youtube.com");
})();
Tomi
  • 3,370
  • 1
  • 16
  • 26

2 Answers2

0

It appears that one of your await statements is awaiting a promise that rejects and you have no error handling to catch a rejection (and thus the UnhandledPromiseRejectionWarning). You can add error handling to catch the rejection and then log what the error is and that should lead you to where the original source of the error is:

const { KameleoLocalApiClient, BuilderForCreateProfile } = require('@kameleo/local-api-client');
const puppeteer = require("puppeteer");
(async () => {
    try {
        const client = new KameleoLocalApiClient();
        const baseProfiles = await client.searchBaseProfiles({
            deviceType: 'desktop',
            browserProduct: 'chrome'
        });

        // Create a new profile with recommended settings
        // for browser fingerprinting protection
        const requestBody = BuilderForCreateProfile
            .forBaseProfile(baseProfiles[0].id)
            .setRecommendedDefaults()
            .build();
        const profile = await client.createProfile({ body: requestBody });

        // Start the browser
        await client.startProfile(profile.id);

        const browserWSEndpoint = `ws://localhost:5050/puppeteer/$(profile.id)`;
        const browser = await puppeteer.connect({browserWSEndpoint, defaultViewport: null});
        const page = await browser.newPage();
        await page.goto("https://youtube.com");
    } catch(e) {
        console.log(e);
        // add appropriate logic to handle errors or cleanup here
    }
})();

And, once you do that you will probably find that your URL is wrong because you're using the wrong string template syntax. change this:

const browserWSEndpoint = `ws://localhost:5050/puppeteer/$(profile.id)`;

to this:

const browserWSEndpoint = `ws://localhost:5050/puppeteer/${profile.id}`;

instead.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • This error appears after typing that in : ErrorEvent {Symbol(kTarget): WebSocket, Symbol(kType): 'error', Symbol(kError): Error: Unexpected server response: 404 …. (c:\Users\Jonat\node_module…, Symbol(kMessage): 'Unexpected server response: 404'} – sean froelich Apr 17 '22 at 18:07
  • That is presumably coming from `await puppeteer.connect(...)` and you will notice that the server it's trying to connect to is reporting a 404. Sounds like you have to either fix the server or fix the endpoint that you're trying to connect to. – jfriend00 Apr 17 '22 at 18:30
  • He missed the string template syntax and the profile.id is not passed with its value, but only the `"$(profile.id)"` is sent. Which is not a valid profile id – Tomi Apr 20 '22 at 09:14
0

You are setting up the browserWSEndpoint in a wrong way. Instead of

const browserWSEndpoint = `ws://localhost:5050/puppeteer/$(profile.id)`;

Use this:

const browserWSEndpoint = `ws://localhost:5050/puppeteer/${profile.id}`;

The difference is made in the javascript string template literals. There you need to use ${} instead of $()

Adding that extra try-catch block is as good idea that is suggested be @jfriend00 . I saw that there was a 404 HTTP status code. This is because Kameleo couldn't find the virtual browser profile because the profileId was not added properly to the URL. It looked like this:

ws://localhost:5050/puppeteer/$(profile.id)

Instead of this:

ws://localhost:5050/puppeteer/df7dd197-5359-407d-8eb8-9d4f5ed13aab

And $(profile.id) is not a valid profileId

Tomi
  • 3,370
  • 1
  • 16
  • 26