From f08f334c8d12dbbf48f279a9864052fb2f92447c Mon Sep 17 00:00:00 2001 From: Omair Date: Tue, 1 Aug 2023 13:59:29 -0400 Subject: [PATCH] playstation: better handling for initial page load --- playstation-plus.js | 4 +++- util.js | 37 ++++++++++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/playstation-plus.js b/playstation-plus.js index 473ce90..cb5371c 100644 --- a/playstation-plus.js +++ b/playstation-plus.js @@ -7,6 +7,7 @@ import { jsonDb, notify, prompt, + retryOnError, } from "./util.js"; import path from "path"; import { existsSync, writeFileSync } from "fs"; @@ -63,7 +64,8 @@ async function main() { } async function performLogin() { - await page.goto(URL_CLAIM, { waitUntil: "networkidle" }); // default 'load' takes forever + // the page gets stuck sometimes and requires a reload + await retryOnError(() => page.goto(URL_CLAIM, { timeout: 20_000, waitUntil: "networkidle" })); const signInLocator = page.locator('span:has-text("Sign in")').first(); const profileIconLocator = page.locator(".profile-icon").first(); diff --git a/util.js b/util.js index 2725745..81e6bd9 100644 --- a/util.js +++ b/util.js @@ -18,6 +18,33 @@ export const jsonDb = async file => { export const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); + +/** + * Retries a Promise a specified number of times on error. + * + * @param {function(): Promise} promiseFn - A function that returns a Promise. + * @param {number} maxRetries - The maximum number of retries to attempt on error. + * @returns {Promise} - A Promise that resolves with the result of the successful attempt or rejects with the last error if all retries fail. + */ +export const retryOnError = (promiseFn, maxRetries = 1) => { + return new Promise((resolve, reject) => { + const executePromise = async (remainingRetries) => { + try { + const result = await promiseFn(); + resolve(result); + } catch (error) { + if (remainingRetries > 0) { + console.log(`Retrying... ${remainingRetries} retries left.`); + executePromise(remainingRetries - 1); // Retry the Promise with one less retry + } else { + reject(error); // No more retries left, reject with the last error + } + } + }; + + executePromise(maxRetries); + }); +}; // date and time as UTC (no timezone offset) in nicely readable and sortable format, e.g., 2022-10-06 12:05:27.313 export const datetimeUTC = (d = new Date()) => d.toISOString().replace('T', ' ').replace('Z', ''); // same as datetimeUTC() but for local timezone, e.g., UTC + 2h for the above in DE @@ -105,11 +132,11 @@ export const notify = (html) => new Promise((resolve, reject) => { const title = cfg.notify_title ? `-t ${cfg.notify_title}` : ''; exec(`apprise ${cfg.notify} -i html '${title}' -b '${html}'`, (error, stdout, stderr) => { if (error) { - console.log(`error: ${error.message}`); - if (error.message.includes('command not found')) { - console.info('Run `pip install apprise`. See https://github.com/vogler/free-games-claimer#notifications'); - } - return resolve(); + console.log(`error: ${error.message}`); + if (error.message.includes('command not found')) { + console.info('Run `pip install apprise`. See https://github.com/vogler/free-games-claimer#notifications'); + } + return resolve(); } if (stderr) console.error(`stderr: ${stderr}`); if (stdout) console.log(`stdout: ${stdout}`);