mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-13 16:22:59 +10:00
Modified 'printResume' Firebase cloud function: implemented basic retry mechanism with waitUntil 'networkidle0' and 'networkidle2', enhanced error handling to return more detailed information
This commit is contained in:
@ -54,42 +54,100 @@ const deleteUserFunctionHandler = async (_, { auth }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.deleteUser = functions
|
/**
|
||||||
.runWith({ memory: '256MB' })
|
* Tries to navigate the page to a given URL.
|
||||||
.https.onCall(deleteUserFunctionHandler);
|
*
|
||||||
|
* @param {puppeteer.Page} page Page.
|
||||||
|
* @param {string} url URL to navigate page to.
|
||||||
|
* @param {puppeteer.PuppeteerLifeCycleEvent} waitUntil When to consider navigation succeeded.
|
||||||
|
* @returns {Promise<string>} Returns null if no error occurred, otherwise returns the error message.
|
||||||
|
*/
|
||||||
|
const tryGotoPage = async (page, url, waitUntil) => {
|
||||||
|
let httpResponse;
|
||||||
|
|
||||||
exports.printResume = functions
|
try {
|
||||||
.runWith({ memory: '1GB' })
|
httpResponse = await page.goto(url, {
|
||||||
.https.onCall(async ({ id, type }, { auth }) => {
|
waitUntil,
|
||||||
if (!id) {
|
});
|
||||||
throw new functions.https.HttpsError(
|
} catch (error) {
|
||||||
'invalid-argument',
|
return `page.goto (waitUntil: "${waitUntil}") threw an error with message "${error.message}"`;
|
||||||
'The function must be called with argument "id" containing the resume ID.',
|
}
|
||||||
);
|
|
||||||
|
if (httpResponse === null) {
|
||||||
|
return `page.goto (waitUntil: "${waitUntil}") returned a null response`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!httpResponse.ok()) {
|
||||||
|
return `page.goto (waitUntil: "${waitUntil}") returned a response with HTTP status ${httpResponse.status()} "${httpResponse.statusText()}"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a page and navigates to a given URL.
|
||||||
|
*
|
||||||
|
* @param {puppeteer.Browser} browser Browser.
|
||||||
|
* @param {string} url URL to navigate to.
|
||||||
|
* @returns {Promise<{page: puppeteer.Page, errors: string[]}>} Returns an object with the page if no error occurred, otherwise returns an object with the list of error messages.
|
||||||
|
*/
|
||||||
|
const gotoPage = async (browser, url) => {
|
||||||
|
const errors = [];
|
||||||
|
|
||||||
|
const waitUntilArray = ['networkidle0', 'networkidle2'];
|
||||||
|
for (let index = 0; index < waitUntilArray.length; index++) {
|
||||||
|
/* eslint-disable no-await-in-loop */
|
||||||
|
const waitUntil = waitUntilArray[index];
|
||||||
|
|
||||||
|
const page = await browser.newPage();
|
||||||
|
await page.setCacheEnabled(false);
|
||||||
|
|
||||||
|
const error = await tryGotoPage(page, url, waitUntil);
|
||||||
|
if (!error) {
|
||||||
|
return { page, errors: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!type) {
|
errors.push(error);
|
||||||
throw new functions.https.HttpsError(
|
await page.close();
|
||||||
'invalid-argument',
|
}
|
||||||
'The function must be called with argument "type" containing the type of resume.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!auth) {
|
return { page: null, errors };
|
||||||
throw new functions.https.HttpsError(
|
};
|
||||||
'failed-precondition',
|
|
||||||
'The function must be called while authenticated.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const printResumeFunctionHandler = async ({ id, type }, { auth }) => {
|
||||||
|
if (!id) {
|
||||||
|
throw new functions.https.HttpsError(
|
||||||
|
'invalid-argument',
|
||||||
|
'The function must be called with argument "id" containing the resume ID.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!type) {
|
||||||
|
throw new functions.https.HttpsError(
|
||||||
|
'invalid-argument',
|
||||||
|
'The function must be called with argument "type" containing the type of resume.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!auth) {
|
||||||
|
throw new functions.https.HttpsError(
|
||||||
|
'failed-precondition',
|
||||||
|
'The function must be called while authenticated.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
const browser = await puppeteer.launch({
|
const browser = await puppeteer.launch({
|
||||||
headless: true,
|
headless: true,
|
||||||
args: ['--no-sandbox'],
|
args: ['--no-sandbox'],
|
||||||
});
|
});
|
||||||
const page = await browser.newPage();
|
|
||||||
await page.goto(BASE_URL + id, {
|
const url = BASE_URL + id;
|
||||||
waitUntil: 'networkidle0',
|
const { page, errors } = await gotoPage(browser, url);
|
||||||
});
|
if (errors && errors.length > 0) {
|
||||||
|
throw new Error(errors.join(' - '));
|
||||||
|
}
|
||||||
|
|
||||||
await timeout(6000);
|
await timeout(6000);
|
||||||
await page.emulateMediaType('print');
|
await page.emulateMediaType('print');
|
||||||
let pdf;
|
let pdf;
|
||||||
@ -124,4 +182,15 @@ exports.printResume = functions
|
|||||||
|
|
||||||
await browser.close();
|
await browser.close();
|
||||||
return Buffer.from(pdf).toString('base64');
|
return Buffer.from(pdf).toString('base64');
|
||||||
});
|
} catch (error) {
|
||||||
|
throw new functions.https.HttpsError('internal', error.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.deleteUser = functions
|
||||||
|
.runWith({ memory: '256MB' })
|
||||||
|
.https.onCall(deleteUserFunctionHandler);
|
||||||
|
|
||||||
|
exports.printResume = functions
|
||||||
|
.runWith({ memory: '1GB' })
|
||||||
|
.https.onCall(printResumeFunctionHandler);
|
||||||
|
|||||||
Reference in New Issue
Block a user