Fix promise timeouts in NPM driver

main
Elbert Alias 4 years ago
parent 675150ad76
commit f5270fb2cf

@ -225,27 +225,26 @@ class Site {
} }
} }
/** promiseTimeout(
* @param {Promise} promise promise,
* @param {string} [errorMessage] errorMessage = 'The website took too long to respond'
* ) {
* @return {Promise} let timeout = null
*/
async promiseTimeout(promise, errorMessage = 'The website took too long to respond') {
let timerId = null;
return Promise.race([ return Promise.race([
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
timerId = setTimeout(() => { timeout = setTimeout(() => {
clearTimeout(timerId); clearTimeout(timeout)
reject(new Error(errorMessage));
}, this.options.maxWait); reject(new Error(errorMessage))
}, this.options.maxWait)
}), }),
promise.then((value) => { promise.then((value) => {
clearTimeout(timerId); clearTimeout(timeout)
return value;
return value
}), }),
]); ])
} }
async goto(url) { async goto(url) {
@ -352,87 +351,98 @@ class Site {
) )
try { try {
await this.promiseTimeout(page.goto(url.href, { waitUntil: 'domcontentloaded' })) await this.promiseTimeout(
page.goto(url.href, { waitUntil: 'domcontentloaded' })
)
await sleep(1000) await sleep(1000)
// Links // Links
const links = await ( const links = await this.promiseTimeout(
await this.promiseTimeout( (
page.evaluateHandle(() => await this.promiseTimeout(
Array.from(document.getElementsByTagName('a')).map( page.evaluateHandle(() =>
({ hash, hostname, href, pathname, protocol, rel }) => ({ Array.from(document.getElementsByTagName('a')).map(
hash, ({ hash, hostname, href, pathname, protocol, rel }) => ({
hostname, hash,
href, hostname,
pathname, href,
protocol, pathname,
rel, protocol,
}) rel,
})
)
) )
), )
) ).jsonValue()
).jsonValue() )
// CSS // CSS
const css = await ( const css = await this.promiseTimeout(
await this.promiseTimeout( (
page.evaluateHandle((maxRows) => { await this.promiseTimeout(
const css = [] page.evaluateHandle((maxRows) => {
const css = []
try {
if (!document.styleSheets.length) { try {
return '' if (!document.styleSheets.length) {
} return ''
}
for (const sheet of Array.from(document.styleSheets)) { for (const sheet of Array.from(document.styleSheets)) {
for (const rules of Array.from(sheet.cssRules)) { for (const rules of Array.from(sheet.cssRules)) {
css.push(rules.cssText) css.push(rules.cssText)
if (css.length >= maxRows) { if (css.length >= maxRows) {
break break
}
} }
} }
} catch (error) {
return ''
} }
} catch (error) {
return ''
}
return css.join('\n') return css.join('\n')
}, this.options.htmlMaxRows), }, this.options.htmlMaxRows)
) )
).jsonValue() ).jsonValue()
)
// Script tags // Script tags
const scripts = await ( const scripts = await this.promiseTimeout(
await this.promiseTimeout( (
page.evaluateHandle(() => await this.promiseTimeout(
Array.from(document.getElementsByTagName('script')) page.evaluateHandle(() =>
.map(({ src }) => src) Array.from(document.getElementsByTagName('script'))
.filter((src) => src) .map(({ src }) => src)
), .filter((src) => src)
) )
).jsonValue() )
).jsonValue()
)
// Meta tags // Meta tags
const meta = await ( const meta = await this.promiseTimeout(
await this.promiseTimeout( (
page.evaluateHandle(() => await this.promiseTimeout(
Array.from(document.querySelectorAll('meta')).reduce( page.evaluateHandle(() =>
(metas, meta) => { Array.from(document.querySelectorAll('meta')).reduce(
const key = (metas, meta) => {
meta.getAttribute('name') || meta.getAttribute('property') const key =
meta.getAttribute('name') || meta.getAttribute('property')
if (key) {
metas[key.toLowerCase()] = [meta.getAttribute('content')] if (key) {
} metas[key.toLowerCase()] = [meta.getAttribute('content')]
}
return metas return metas
}, },
{} {}
)
) )
), )
) ).jsonValue()
).jsonValue() )
// JavaScript // JavaScript
const js = await this.promiseTimeout( const js = await this.promiseTimeout(
@ -467,7 +477,7 @@ class Site {
Wappalyzer.technologies Wappalyzer.technologies
.filter(({ js }) => Object.keys(js).length) .filter(({ js }) => Object.keys(js).length)
.map(({ name, js }) => ({ name, chains: Object.keys(js) })) .map(({ name, js }) => ({ name, chains: Object.keys(js) }))
), )
) )
// Cookies // Cookies
@ -565,7 +575,11 @@ class Site {
return reducedLinks return reducedLinks
} catch (error) { } catch (error) {
this.error(error) if (error.constructor.name === 'TimeoutError') {
throw new Error('The website took too long to respond')
}
throw new Error(error.message)
} }
} }

Loading…
Cancel
Save