Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Improve the error message about download servers unavailability #399

Merged
merged 4 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions install-npm.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,14 @@ async function main() {
`The Chromedriver install script cannot be found at '${BUILD_PATH}'. ` +
`Building appium-chromedriver package`
);
const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
const isWindows = process.platform === 'win32';
const npmCommand = `npm${isWindows ? '.cmd' : ''}`;
try {
await exec(npmCommand, ['run', 'build'], {logger: log, cwd: __dirname});
await exec(npmCommand, ['run', 'build'], {
logger: log,
cwd: __dirname,
shell: isWindows,
});
} catch (e) {
throw new Error(`appium-chromedriver package cannot be built: ${util.inspect(e)}`);
}
Expand Down
53 changes: 42 additions & 11 deletions lib/storage-client/storage-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ import {compareVersions} from 'compare-versions';
import semver from 'semver';

const MAX_PARALLEL_DOWNLOADS = 5;
const STORAGE_INFOS = /** @type {readonly StorageInfo[]} */ ([{
url: GOOGLEAPIS_CDN,
accept: 'application/xml',
}, {
url: `${CHROMELABS_URL}/chrome-for-testing/known-good-versions-with-downloads.json`,
accept: 'application/json',
}]);

const log = logger.getLogger('ChromedriverStorageClient');

Expand Down Expand Up @@ -60,19 +67,37 @@ export class ChromedriverStorageClient {
* @returns {Promise<ChromedriverDetailsMapping>}
*/
async retrieveMapping(shouldParseNotes = true) {
const [xmlStr, jsonStr] = await B.all([
[GOOGLEAPIS_CDN, 'application/xml'],
[`${CHROMELABS_URL}/chrome-for-testing/known-good-versions-with-downloads.json`, 'application/json'],
]
.map(([url, contentType]) => url
? retrieveData(url, {
/** @type {(si: StorageInfo) => Promise<string|undefined>} */
const retrieveResponseSafely = async (/** @type {StorageInfo} */ {url, accept}) => {
try {
return await retrieveData(url, {
'user-agent': USER_AGENT,
accept: `${contentType}, */*`,
}, {timeout: this.timeout})
: B.resolve()
));
accept: `${accept}, */*`,
}, {timeout: this.timeout});
} catch (e) {
log.debug(/** @type {Error} */(e).stack);
log.warn(
`Cannot retrieve Chromedrivers info from ${url}. ` +
`Make sure this URL is accessible from your network. ` +
`Original error: ${/** @type {Error} */(e).message}`
);
}
};
const [xmlStr, jsonStr] = await B.all(STORAGE_INFOS.map(retrieveResponseSafely));
// Apply the best effort approach and fetch the mapping from at least one server if possible.
// We'll fail later anyway if the target chromedriver version is not there.
if (!xmlStr && !jsonStr) {
throw new Error(
`Cannot retrieve the information about available Chromedrivers from ` +
`${STORAGE_INFOS.map(({url}) => url)}. Please make sure these URLs are avilable ` +
`within your local network, check Appium server logs and/or ` +
`consult the driver troubleshooting guide.`
);
}
this.mapping = xmlStr ? await parseGoogleapiStorageXml(xmlStr, shouldParseNotes) : {};
Object.assign(this.mapping, parseKnownGoodVersionsWithDownloadsJson(jsonStr));
if (jsonStr) {
Object.assign(this.mapping, parseKnownGoodVersionsWithDownloadsJson(jsonStr));
}
return this.mapping;
}

Expand Down Expand Up @@ -392,3 +417,9 @@ export default ChromedriverStorageClient;
* @typedef {import('../types').ChromedriverDetails} ChromedriverDetails
* @typedef {import('../types').ChromedriverDetailsMapping} ChromedriverDetailsMapping
*/

/**
* @typedef {Object} StorageInfo
* @property {string} url
* @property {string} accept
*/
Loading