diff --git a/lib/config/presets.ts b/lib/config/presets.ts index d2672521b658bee5018339603d70ab18b7a61b89..986b8518b9cd224dc968c5abd45326ff5d46793e 100644 --- a/lib/config/presets.ts +++ b/lib/config/presets.ts @@ -8,6 +8,11 @@ import * as gitlab from '../datasource/gitlab'; import { RenovateConfig } from './common'; import { mergeChildConfig } from './utils'; import { regEx } from '../util/regex'; +import { + CONFIG_VALIDATION, + DATASOURCE_FAILURE, + PLATFORM_FAILURE, +} from '../constants/error-messages'; const datasources = { github, @@ -166,12 +171,12 @@ export async function resolveConfigPresets( logger.debug({ err }, 'Preset fetch error'); // istanbul ignore if if ( - err.message === 'platform-failure' || - err.message === 'registry-failure' + err.message === PLATFORM_FAILURE || + err.message === DATASOURCE_FAILURE ) { throw err; } - const error = new Error('config-validation'); + const error = new Error(CONFIG_VALIDATION); if (err.message === 'dep not found') { error.validationError = `Cannot find preset's package (${preset})`; } else if (err.message === 'preset renovate-config not found') { diff --git a/lib/constants/error-messages.ts b/lib/constants/error-messages.ts new file mode 100644 index 0000000000000000000000000000000000000000..8aacceae24b882626e024772a0d4530b2207a4a7 --- /dev/null +++ b/lib/constants/error-messages.ts @@ -0,0 +1,47 @@ +// System error +export const SYSTEM_INSUFFICIENT_DISK_SPACE = 'disk-space'; + +// Platform Error +export const PLATFORM_AUTHENTICATION_ERROR = 'authentication-error'; +export const PLATFORM_BAD_CREDENTIALS = 'bad-credentials'; +export const PLATFORM_FAILURE = 'platform-failure'; +export const PLATFORM_INTEGRATION_UNAUTHORIZED = 'integration-unauthorized'; +export const PLATFORM_NOT_FOUND = 'platform-not-found'; +export const PLATFORM_RATE_LIMIT_EXCEEDED = 'rate-limit-exceeded'; + +// Config Error +export const CONFIG_VALIDATION = 'config-validation'; + +// Repository Error +export const REPOSITORY_ACCESS_FORBIDDEN = 'forbidden'; +export const REPOSITORY_ARCHIVED = 'archived'; +export const REPOSITORY_BLOCKED = 'blocked'; +export const REPOSITORY_CANNOT_FORK = 'cannot-fork'; +export const REPOSITORY_CHANGED = 'repository-changed'; +export const REPOSITORY_DISABLED = 'disabled'; +export const REPOSITORY_EMPTY = 'empty'; +export const REPOSITORY_FORKED = 'fork'; +export const REPOSITORY_MIRRORED = 'mirror'; +export const REPOSITORY_NOT_FOUND = 'not-found'; +export const REPOSITORY_NO_VULNERABILITY = 'no-vulnerability-alerts'; +export const REPOSITORY_RENAMED = 'renamed'; +export const REPOSITORY_TEMPORARY_ERROR = 'temporary-error'; +export const REPOSITORY_UNINITIATED = 'uninitiated'; + +// Manager Error +export const MANAGER_LOCKFILE_ERROR = 'lockfile-error'; +export const MANAGER_NO_PACKAGE_FILES = 'no-package-files'; + +// Datasource error +export const DATASOURCE_FAILURE = 'registry-failure'; + +// Worker Error +export const WORKER_FILE_UPDATE_FAILED = 'update-failure'; + +// Bundler Error +export const BUNDLER_COULD_NOT_RESOLVE = 'bundler-resolve'; +export const BUNDLER_INVALID_CREDENTIALS = 'bundler-credentials'; +export const BUNDLER_UNKNOWN_ERROR = 'bundler-unknown'; + +// Unknown Error +export const UNKNOWN_ERROR = 'unknown-error'; diff --git a/lib/datasource/cargo/index.ts b/lib/datasource/cargo/index.ts index 41c65bf4d96c10bc43dda9935058c7772dce5d4a..d36ccdc120729f6f24851dafd6c6fa995cd5c8c6 100644 --- a/lib/datasource/cargo/index.ts +++ b/lib/datasource/cargo/index.ts @@ -1,6 +1,7 @@ import { logger } from '../../logger'; import got from '../../util/got'; import { PkgReleaseConfig, ReleaseResult, Release } from '../common'; +import { DATASOURCE_FAILURE } from '../../constants/error-messages'; export async function getPkgReleases({ lookupName, @@ -101,7 +102,7 @@ export async function getPkgReleases({ (err.statusCode >= 500 && err.statusCode < 600) ) { logger.warn({ lookupName, err }, `cargo crates.io registry failure`); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } logger.warn( { err, lookupName }, diff --git a/lib/datasource/dart/index.ts b/lib/datasource/dart/index.ts index 2b3723f34b2387e050977fd58f877db9cf92b376..3d7933743ba835b627cdc6724329c370a736610d 100644 --- a/lib/datasource/dart/index.ts +++ b/lib/datasource/dart/index.ts @@ -1,6 +1,7 @@ import got from '../../util/got'; import { logger } from '../../logger'; import { ReleaseResult, PkgReleaseConfig } from '../common'; +import { DATASOURCE_FAILURE } from '../../constants/error-messages'; export async function getPkgReleases({ lookupName, @@ -34,7 +35,7 @@ export async function getPkgReleases({ (err.statusCode >= 500 && err.statusCode < 600) ) { logger.warn({ lookupName, err }, `pub.dartlang.org registry failure`); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } logger.warn( { err, lookupName }, diff --git a/lib/datasource/docker/index.ts b/lib/datasource/docker/index.ts index 793ee45cbb97d38a1539cbdf579790540b8051ab..564b81583638f8ffe6996802c882db7b527b1351 100644 --- a/lib/datasource/docker/index.ts +++ b/lib/datasource/docker/index.ts @@ -10,6 +10,7 @@ import got from '../../util/got'; import * as hostRules from '../../util/host-rules'; import { PkgReleaseConfig, ReleaseResult } from '../common'; import { GotResponse } from '../../platform'; +import { DATASOURCE_FAILURE } from '../../constants/error-messages'; // TODO: add got typings when available // TODO: replace www-authenticate with https://www.npmjs.com/package/auth-header ? @@ -162,15 +163,15 @@ async function getAuthHeaders( if (err.name === 'RequestError' && registry.endsWith('docker.io')) { logger.debug({ err }, 'err'); logger.info('Docker registry error: RequestError'); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } if (err.statusCode === 429 && registry.endsWith('docker.io')) { logger.warn({ err }, 'docker registry failure: too many requests'); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } if (err.statusCode >= 500 && err.statusCode < 600) { logger.warn({ err }, 'docker registry failure: internal error'); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } logger.warn( { registry, dockerRepository: repository, err }, @@ -210,7 +211,7 @@ async function getManifestResponse( }); return manifestResponse; } catch (err) /* istanbul ignore next */ { - if (err.message === 'registry-failure') { + if (err.message === DATASOURCE_FAILURE) { throw err; } if (err.statusCode === 401) { @@ -235,7 +236,7 @@ async function getManifestResponse( } if (err.statusCode === 429 && registry.endsWith('docker.io')) { logger.warn({ err }, 'docker registry failure: too many requests'); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } if (err.statusCode >= 500 && err.statusCode < 600) { logger.info( @@ -247,7 +248,7 @@ async function getManifestResponse( }, 'docker registry failure: internal error' ); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } if (err.code === 'ETIMEDOUT') { logger.info( @@ -311,7 +312,7 @@ export async function getDigest( await renovateCache.set(cacheNamespace, cacheKey, digest, cacheMinutes); return digest; } catch (err) /* istanbul ignore next */ { - if (err.message === 'registry-failure') { + if (err.message === DATASOURCE_FAILURE) { throw err; } logger.info( @@ -366,7 +367,7 @@ async function getTags( await renovateCache.set(cacheNamespace, cacheKey, tags, cacheMinutes); return tags; } catch (err) /* istanbul ignore next */ { - if (err.message === 'registry-failure') { + if (err.message === DATASOURCE_FAILURE) { throw err; } logger.debug( @@ -393,14 +394,14 @@ async function getTags( { registry, dockerRepository: repository, err }, 'docker registry failure: too many requests' ); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } if (err.statusCode >= 500 && err.statusCode < 600) { logger.warn( { registry, dockerRepository: repository, err }, 'docker registry failure: internal error' ); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } if (err.code === 'ETIMEDOUT') { logger.info( @@ -524,7 +525,7 @@ async function getLabels( await renovateCache.set(cacheNamespace, cacheKey, labels, cacheMinutes); return labels; } catch (err) { - if (err.message === 'registry-failure') { + if (err.message === DATASOURCE_FAILURE) { throw err; } if (err.statusCode === 401) { diff --git a/lib/datasource/gradle-version/index.ts b/lib/datasource/gradle-version/index.ts index e0b42e3511540e7a1b379f23ce00b828b82f8920..5c0006f27189b3c6241e6b8de32e69c8077a38ed 100644 --- a/lib/datasource/gradle-version/index.ts +++ b/lib/datasource/gradle-version/index.ts @@ -3,6 +3,7 @@ import is from '@sindresorhus/is'; import { logger } from '../../logger'; import got from '../../util/got'; import { PkgReleaseConfig, ReleaseResult, Release } from '../common'; +import { DATASOURCE_FAILURE } from '../../constants/error-messages'; const GradleVersionsServiceUrl = 'https://services.gradle.org/versions/all'; @@ -48,7 +49,7 @@ export async function getPkgReleases({ if (!(err.statusCode === 404 || err.code === 'ENOTFOUND')) { logger.warn({ err }, 'Gradle release lookup failure: Unknown error'); } - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } }) ); diff --git a/lib/datasource/helm/index.ts b/lib/datasource/helm/index.ts index 5913f5ca3f8e91f7d58b38a2c59e79a2a24a091e..8552b09cb6bc7acf123d5e6a2a2646e37cb382ba 100644 --- a/lib/datasource/helm/index.ts +++ b/lib/datasource/helm/index.ts @@ -1,4 +1,5 @@ import yaml from 'js-yaml'; +import { DATASOURCE_FAILURE } from '../../constants/error-messages'; import { PkgReleaseConfig, ReleaseResult } from '../common'; import got from '../../util/got'; @@ -35,7 +36,7 @@ export async function getRepositoryData( (err.statusCode >= 500 && err.statusCode < 600) ) { logger.warn({ err }, `${repository} server error`); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } logger.warn({ err }, `${repository} lookup failure: Unknown error`); return null; diff --git a/lib/datasource/hex/index.ts b/lib/datasource/hex/index.ts index 85cfa46d4f5b05c681baf1df334e057f088e1efe..999ec4eb5f4831ec7ac9b93b62f626d5d727c1a9 100644 --- a/lib/datasource/hex/index.ts +++ b/lib/datasource/hex/index.ts @@ -1,6 +1,7 @@ import { logger } from '../../logger'; import got from '../../util/got'; import { ReleaseResult, PkgReleaseConfig } from '../common'; +import { DATASOURCE_FAILURE } from '../../constants/error-messages'; interface HexRelease { html_url: string; @@ -65,7 +66,7 @@ export async function getPkgReleases({ (err.statusCode >= 500 && err.statusCode < 600) ) { logger.warn({ lookupName, err }, `hex.pm registry failure`); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } if (err.statusCode === 401) { diff --git a/lib/datasource/maven/util.ts b/lib/datasource/maven/util.ts index 4ca420875101c8617be3184bd0d9126fcb60000a..a06b0cf83745193a79b08334b6bc183cabbb2e36 100644 --- a/lib/datasource/maven/util.ts +++ b/lib/datasource/maven/util.ts @@ -1,6 +1,7 @@ import url from 'url'; import got from '../../util/got'; import { logger } from '../../logger'; +import { DATASOURCE_FAILURE } from '../../constants/error-messages'; function isMavenCentral(pkgUrl: url.URL | string): boolean { return ( @@ -70,7 +71,7 @@ export async function downloadHttpProtocol( } else if (isTemporalError(err)) { logger.info({ failedUrl, err }, 'Temporary error'); if (isMavenCentral(pkgUrl)) { - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } } else if (isConnectionError(err)) { // istanbul ignore next diff --git a/lib/datasource/npm/get.ts b/lib/datasource/npm/get.ts index ab2f8010141c94d6bf3c5e6713adc07d95c0a476..3facf873c31de6407084c6528ef73293e2c7b1a9 100644 --- a/lib/datasource/npm/get.ts +++ b/lib/datasource/npm/get.ts @@ -10,6 +10,7 @@ import got from '../../util/got'; import { maskToken } from '../../util/mask'; import { getNpmrc } from './npmrc'; import { Release, ReleaseResult } from '../common'; +import { DATASOURCE_FAILURE } from '../../constants/error-messages'; let memcache = {}; @@ -234,7 +235,7 @@ export async function getDependency( } if (regUrl.startsWith('https://registry.npmjs.org')) { logger.warn({ err, regUrl, depName: name }, 'npm registry failure'); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } // istanbul ignore next return null; diff --git a/lib/datasource/packagist/index.ts b/lib/datasource/packagist/index.ts index 281d793c8764cfe703b7a48dfb37c00f5c3c2491..bad5aefb52e95e49ca5889281bb1be72dfd1f36c 100644 --- a/lib/datasource/packagist/index.ts +++ b/lib/datasource/packagist/index.ts @@ -8,6 +8,7 @@ import { logger } from '../../logger'; import got, { GotJSONOptions } from '../../util/got'; import * as hostRules from '../../util/host-rules'; import { PkgReleaseConfig, ReleaseResult } from '../common'; +import { DATASOURCE_FAILURE } from '../../constants/error-messages'; function getHostOpts(url: string): GotJSONOptions { const opts: GotJSONOptions = { @@ -287,7 +288,7 @@ async function packageLookup( err.host === 'packagist.org' ) { logger.info('Packagist.org timeout'); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } logger.warn({ err, name }, 'packagist registry failure: Unknown error'); return null; diff --git a/lib/datasource/ruby-version/index.ts b/lib/datasource/ruby-version/index.ts index ffcbbe50c04682b13058dba947133694c48809ac..39154e7fe1344b2f1898807d68c7bd1d9e1ba129 100644 --- a/lib/datasource/ruby-version/index.ts +++ b/lib/datasource/ruby-version/index.ts @@ -4,6 +4,7 @@ import { logger } from '../../logger'; import got from '../../util/got'; import { isVersion } from '../../versioning/ruby'; import { PkgReleaseConfig, ReleaseResult } from '../common'; +import { DATASOURCE_FAILURE } from '../../constants/error-messages'; const rubyVersionsUrl = 'https://www.ruby-lang.org/en/downloads/releases/'; @@ -48,9 +49,9 @@ export async function getPkgReleases( return res; } catch (err) { if (err && (err.statusCode === 404 || err.code === 'ENOTFOUND')) { - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } logger.warn({ err }, 'Ruby release lookup failure: Unknown error'); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } } diff --git a/lib/datasource/rubygems/get-rubygems-org.ts b/lib/datasource/rubygems/get-rubygems-org.ts index 3b9c1491999d96779d3a5a38302582d2d331e309..208f814fd55743b97dce8e32bcfda5d9ae261bc5 100644 --- a/lib/datasource/rubygems/get-rubygems-org.ts +++ b/lib/datasource/rubygems/get-rubygems-org.ts @@ -1,6 +1,7 @@ import got from '../../util/got'; import { logger } from '../../logger'; import { ReleaseResult } from '../common'; +import { DATASOURCE_FAILURE } from '../../constants/error-messages'; let lastSync = new Date('2000-01-01'); let packageReleases: Record<string, string[]> = Object.create(null); // Because we might need a "constructor" key @@ -26,7 +27,7 @@ async function updateRubyGemsVersions(): Promise<void> { logger.warn({ err }, 'Rubygems error - resetting cache'); contentLength = 0; packageReleases = Object.create(null); // Because we might need a "constructor" key - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } logger.debug('Rubygems: No update'); lastSync = new Date(); diff --git a/lib/datasource/rubygems/get.ts b/lib/datasource/rubygems/get.ts index a851facda09e5821f6da6d4ccd1b64c9b433d949..76a627b7b4debc216e1710971ad75d769a59cb0d 100644 --- a/lib/datasource/rubygems/get.ts +++ b/lib/datasource/rubygems/get.ts @@ -5,6 +5,7 @@ import { maskToken } from '../../util/mask'; import retriable from './retriable'; import { UNAUTHORIZED, FORBIDDEN, NOT_FOUND } from './errors'; import { ReleaseResult } from '../common'; +import { DATASOURCE_FAILURE } from '../../constants/error-messages'; const INFO_PATH = '/api/v1/gems'; const VERSIONS_PATH = '/api/v1/versions'; @@ -29,7 +30,7 @@ const processError = ({ err, ...rest }): null => { break; default: logger.debug(data, 'RubyGems lookup failure'); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } return null; }; diff --git a/lib/manager/bundler/artifacts.ts b/lib/manager/bundler/artifacts.ts index 3997a8a7cb0cb431438afd07013b1f971cc9f30e..b1a150562564e84ccb9feec6c45466729c6d1625 100644 --- a/lib/manager/bundler/artifacts.ts +++ b/lib/manager/bundler/artifacts.ts @@ -12,6 +12,11 @@ import { } from '../../versioning/ruby'; import { UpdateArtifactsConfig, UpdateArtifactsResult } from '../common'; import { platform } from '../../platform'; +import { + BUNDLER_COULD_NOT_RESOLVE, + BUNDLER_INVALID_CREDENTIALS, + BUNDLER_UNKNOWN_ERROR, +} from '../../constants/error-messages'; export async function updateArtifacts( packageFileName: string, @@ -149,8 +154,8 @@ export async function updateArtifacts( { err }, 'Gemfile.lock update failed due to missing credentials' ); - global.repoCache.bundlerArtifactsError = 'bundler-credentials'; - throw new Error('bundler-credentials'); + global.repoCache.bundlerArtifactsError = BUNDLER_INVALID_CREDENTIALS; + throw new Error(BUNDLER_INVALID_CREDENTIALS); } const resolveMatchRe = new RegExp('\\s+(.*) was resolved to', 'g'); if (err.stderr && err.stderr.match(resolveMatchRe)) { @@ -180,10 +185,10 @@ export async function updateArtifacts( } logger.warn({ err }, 'Cannot resolve bundler lock update error'); // Do not set global.repoCache because we don't want to stop trying other branches - throw new Error('bundler-resolve'); + throw new Error(BUNDLER_COULD_NOT_RESOLVE); } logger.warn({ err }, 'Unknown bundler lock file update error'); - global.repoCache.bundlerArtifactsError = 'bundler-unknown'; - throw new Error('bundler-unknown'); + global.repoCache.bundlerArtifactsError = BUNDLER_UNKNOWN_ERROR; + throw new Error(BUNDLER_UNKNOWN_ERROR); } } diff --git a/lib/manager/composer/artifacts.ts b/lib/manager/composer/artifacts.ts index a1242ab12b80d4e827298f3799b27a47c0e6ec45..f6a1b3592d8867a28a17d98ce1114aee9d6c25d1 100644 --- a/lib/manager/composer/artifacts.ts +++ b/lib/manager/composer/artifacts.ts @@ -8,6 +8,7 @@ import { logger } from '../../logger'; import * as hostRules from '../../util/host-rules'; import { getChildProcessEnv } from '../../util/exec/env'; import { platform } from '../../platform'; +import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../constants/error-messages'; export async function updateArtifacts( packageFileName: string, @@ -166,7 +167,7 @@ export async function updateArtifacts( err.message && err.message.includes('write error (disk full?)') ) { - throw new Error('disk-space'); + throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE); } else { logger.debug({ err }, 'Failed to generate composer.lock'); } diff --git a/lib/manager/gradle/index.ts b/lib/manager/gradle/index.ts index c5807d02551976e12bec7a3ccbd2e3f9a526afab..334f294242133436b1c962d69c49f5e909536af2 100644 --- a/lib/manager/gradle/index.ts +++ b/lib/manager/gradle/index.ts @@ -3,6 +3,7 @@ import upath from 'upath'; import { exec } from '../../util/exec'; import { logger } from '../../logger'; +import { DATASOURCE_FAILURE } from '../../constants/error-messages'; import { init, @@ -87,7 +88,7 @@ async function executeGradle( } logger.warn({ err, cmd }, 'Gradle run failed'); logger.info('Aborting Renovate due to Gradle lookup errors'); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } logger.debug(stdout + stderr); logger.info('Gradle report complete'); diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts index 72b3d68de6830da1fd1007a8fbc988fac6d60151..ef0352bc7dfe6a856f339f2c5891a95bca2e577c 100644 --- a/lib/manager/npm/extract/index.ts +++ b/lib/manager/npm/extract/index.ts @@ -16,6 +16,7 @@ import { } from '../../common'; import { NpmPackage } from './common'; import { platform } from '../../../platform'; +import { CONFIG_VALIDATION } from '../../../constants/error-messages'; export async function extractPackageFile( content: string, @@ -38,7 +39,7 @@ export async function extractPackageFile( return null; } if (fileName !== 'package.json' && packageJson.renovate) { - const error = new Error('config-validation'); + const error = new Error(CONFIG_VALIDATION); error.configFile = fileName; error.validationError = 'Nested package.json must not contain renovate configuration. Please use `packageRules` with `paths` in your main config instead.'; diff --git a/lib/manager/npm/post-update/index.ts b/lib/manager/npm/post-update/index.ts index 0a615c2e71184094ecc3962a3ba605f7e1ce95dd..fe48b52a463ce0b512d46be691a97b29fdf45719 100644 --- a/lib/manager/npm/post-update/index.ts +++ b/lib/manager/npm/post-update/index.ts @@ -11,6 +11,10 @@ import * as hostRules from '../../../util/host-rules'; import { getChildProcessEnv } from '../../../util/exec/env'; import { PostUpdateConfig, PackageFile, Upgrade } from '../../common'; import { platform } from '../../../platform'; +import { + SYSTEM_INSUFFICIENT_DISK_SPACE, + DATASOURCE_FAILURE, +} from '../../../constants/error-messages'; // Strips empty values, deduplicates, and returns the directories from filenames // istanbul ignore next @@ -381,7 +385,7 @@ export async function getAdditionalFiles( { dependency: upgrade.depName, type: 'npm' }, 'lock file failed for the dependency being updated - skipping branch creation' ); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } } } @@ -433,7 +437,7 @@ export async function getAdditionalFiles( { dependency: upgrade.depName, type: 'yarn' }, 'lock file failed for the dependency being updated - skipping branch creation' ); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } /* eslint-enable no-useless-escape */ } @@ -519,7 +523,7 @@ export async function getAdditionalFiles( { dependency: upgrade.depName, type: 'pnpm' }, 'lock file failed for the dependency being updated - skipping branch creation' ); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } } } @@ -575,7 +579,7 @@ export async function getAdditionalFiles( res.stderr && res.stderr.includes('ENOSPC: no space left on device') ) { - throw new Error('disk-space'); + throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE); } for (const upgrade of config.upgrades) { /* eslint-disable no-useless-escape */ @@ -588,7 +592,7 @@ export async function getAdditionalFiles( { dependency: upgrade.depName, type: 'yarn' }, 'lock file failed for the dependency being updated - skipping branch creation' ); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } /* eslint-enable no-useless-escape */ if ( @@ -600,7 +604,7 @@ export async function getAdditionalFiles( { dependency: upgrade.depName, type: 'npm' }, 'lock file failed for the dependency being updated - skipping branch creation' ); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } } artifactErrors.push({ diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts index f6cc933d5e4fa85405698abbeb55576eb2084e54..248d9f6d84b42a3be9fd1c4f96248e4cb01000ef 100644 --- a/lib/manager/npm/post-update/npm.ts +++ b/lib/manager/npm/post-update/npm.ts @@ -4,6 +4,7 @@ import { getInstalledPath } from 'get-installed-path'; import { exec } from '../../../util/exec'; import { logger } from '../../../logger'; import { PostUpdateConfig, Upgrade } from '../../common'; +import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../../constants/error-messages'; export interface GenerateLockFileResult { error?: boolean; @@ -135,7 +136,7 @@ export async function generateLockFile( } // istanbul ignore if if (stderr && stderr.includes('ENOSPC: no space left on device')) { - throw new Error('disk-space'); + throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE); } const duration = process.hrtime(startTime); const seconds = Math.round(duration[0] + duration[1] / 1e9); diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts index 3c48a995a26a8b333dcc7b491b2f86197c6ace4c..9c5b0a9a5cfb5f7009c724081de65099655fa5d6 100644 --- a/lib/manager/npm/post-update/yarn.ts +++ b/lib/manager/npm/post-update/yarn.ts @@ -4,6 +4,10 @@ import { getInstalledPath } from 'get-installed-path'; import { exec } from '../../../util/exec'; import { logger } from '../../../logger'; import { PostUpdateConfig, Upgrade } from '../../common'; +import { + SYSTEM_INSUFFICIENT_DISK_SPACE, + DATASOURCE_FAILURE, +} from '../../../constants/error-messages'; export interface GenerateLockFileResult { error?: boolean; @@ -176,14 +180,14 @@ export async function generateLockFile( ); if (err.stderr) { if (err.stderr.includes('ENOSPC: no space left on device')) { - throw new Error('disk-space'); + throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE); } if ( err.stderr.includes('The registry may be down.') || err.stderr.includes('getaddrinfo ENOTFOUND registry.yarnpkg.com') || err.stderr.includes('getaddrinfo ENOTFOUND registry.npmjs.org') ) { - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } } return { error: true, stderr: err.stderr }; diff --git a/lib/platform/azure/index.ts b/lib/platform/azure/index.ts index efbe7292974db7aa14ef4c09f19c9471bbe9f778..95b3ead1a948041ac5e18d75c1c052b138b6caeb 100644 --- a/lib/platform/azure/index.ts +++ b/lib/platform/azure/index.ts @@ -20,6 +20,7 @@ import { } from '../common'; import { sanitize } from '../../util/sanitize'; import { smartTruncate } from '../utils/pr-body'; +import { REPOSITORY_DISABLED } from '../../constants/error-messages'; interface Config { storage: GitStorage; @@ -129,7 +130,7 @@ export async function initRepo({ // Do nothing } if (renovateConfig && renovateConfig.enabled === false) { - throw new Error('disabled'); + throw new Error(REPOSITORY_DISABLED); } } diff --git a/lib/platform/bitbucket-server/index.ts b/lib/platform/bitbucket-server/index.ts index 729aa03ee707d292d9c1b8d948ca0dbbcad42b10..c534bc2404d36b11c6824f196e201a42064ba08a 100644 --- a/lib/platform/bitbucket-server/index.ts +++ b/lib/platform/bitbucket-server/index.ts @@ -19,7 +19,11 @@ import { } from '../common'; import { sanitize } from '../../util/sanitize'; import { smartTruncate } from '../utils/pr-body'; - +import { + REPOSITORY_CHANGED, + REPOSITORY_DISABLED, + REPOSITORY_NOT_FOUND, +} from '../../constants/error-messages'; /* * Version: 5.3 (EOL Date: 15 Aug 2019) * See following docs for api information: @@ -156,7 +160,7 @@ export async function initRepo({ // Do nothing } if (renovateConfig && renovateConfig.enabled === false) { - throw new Error('disabled'); + throw new Error(REPOSITORY_DISABLED); } } @@ -211,7 +215,7 @@ export async function initRepo({ } catch (err) /* istanbul ignore next */ { logger.debug(err); if (err.statusCode === 404) { - throw new Error('not-found'); + throw new Error(REPOSITORY_NOT_FOUND); } logger.info({ err }, 'Unknown Bitbucket initRepo error'); throw err; @@ -514,7 +518,7 @@ export async function getBranchStatus( } if (!(await branchExists(branchName))) { - throw new Error('repository-changed'); + throw new Error(REPOSITORY_CHANGED); } try { @@ -683,7 +687,7 @@ export async function addReviewers( try { const pr = await getPr(prNo); if (!pr) { - throw Object.assign(new Error('not-found'), { statusCode: 404 }); + throw new Error(REPOSITORY_NOT_FOUND); } const reviewersSet = new Set([...pr.reviewers, ...reviewers]); @@ -702,9 +706,9 @@ export async function addReviewers( await getPr(prNo, true); } catch (err) { if (err.statusCode === 404) { - throw new Error('not-found'); + throw new Error(REPOSITORY_NOT_FOUND); } else if (err.statusCode === 409) { - throw new Error('repository-changed'); + throw new Error(REPOSITORY_CHANGED); } else { logger.fatal({ err }, `Failed to add reviewers ${reviewers} to #${prNo}`); throw err; @@ -921,7 +925,7 @@ export async function createPr({ 'Empty pull request - deleting branch so it can be recreated next run' ); await deleteBranch(branchName); - throw new Error('repository-changed'); + throw new Error(REPOSITORY_CHANGED); } throw err; } @@ -969,7 +973,7 @@ export async function updatePr( try { const pr = await getPr(prNo); if (!pr) { - throw Object.assign(new Error('not-found'), { statusCode: 404 }); + throw Object.assign(new Error(REPOSITORY_NOT_FOUND), { statusCode: 404 }); } const { body } = await api.put<{ version: number }>( @@ -987,9 +991,9 @@ export async function updatePr( updatePrVersion(prNo, body.version); } catch (err) { if (err.statusCode === 404) { - throw new Error('not-found'); + throw new Error(REPOSITORY_NOT_FOUND); } else if (err.statusCode === 409) { - throw new Error('repository-changed'); + throw new Error(REPOSITORY_CHANGED); } else { logger.fatal({ err }, `Failed to update PR`); throw err; @@ -1007,7 +1011,7 @@ export async function mergePr( try { const pr = await getPr(prNo); if (!pr) { - throw Object.assign(new Error('not-found'), { statusCode: 404 }); + throw Object.assign(new Error(REPOSITORY_NOT_FOUND), { statusCode: 404 }); } const { body } = await api.post<{ version: number }>( `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/merge?version=${pr.version}` @@ -1015,7 +1019,7 @@ export async function mergePr( updatePrVersion(prNo, body.version); } catch (err) { if (err.statusCode === 404) { - throw new Error('not-found'); + throw new Error(REPOSITORY_NOT_FOUND); } else if (err.statusCode === 409) { logger.warn({ err }, `Failed to merge PR`); return false; diff --git a/lib/platform/bitbucket/index.ts b/lib/platform/bitbucket/index.ts index 4c7a5ebb127e658c5c5c6f879fd6340d6b9ed8a0..2411c79fa956a1e999f01398436109b54b36b75f 100644 --- a/lib/platform/bitbucket/index.ts +++ b/lib/platform/bitbucket/index.ts @@ -20,6 +20,10 @@ import { } from '../common'; import { sanitize } from '../../util/sanitize'; import { smartTruncate } from '../utils/pr-body'; +import { + REPOSITORY_DISABLED, + REPOSITORY_NOT_FOUND, +} from '../../constants/error-messages'; let config: utils.Config = {} as any; @@ -100,7 +104,7 @@ export async function initRepo({ // Do nothing } if (renovateConfig && renovateConfig.enabled === false) { - throw new Error('disabled'); + throw new Error(REPOSITORY_DISABLED); } } @@ -115,7 +119,7 @@ export async function initRepo({ logger.debug(`${repository} owner = ${config.owner}`); } catch (err) /* istanbul ignore next */ { if (err.statusCode === 404) { - throw new Error('not-found'); + throw new Error(REPOSITORY_NOT_FOUND); } logger.info({ err }, 'Unknown Bitbucket initRepo error'); throw err; diff --git a/lib/platform/git/storage.ts b/lib/platform/git/storage.ts index 6da8ba661b461ec9e608975195d4504aad35b0d8..62d4b11d3bf74c9b3d3aa5414d2468bff78aabcf 100644 --- a/lib/platform/git/storage.ts +++ b/lib/platform/git/storage.ts @@ -5,6 +5,13 @@ import Git from 'simple-git/promise'; import URL from 'url'; import { logger } from '../../logger'; import * as limits from '../../workers/global/limits'; +import { + CONFIG_VALIDATION, + PLATFORM_FAILURE, + REPOSITORY_CHANGED, + REPOSITORY_EMPTY, + REPOSITORY_TEMPORARY_ERROR, +} from '../../constants/error-messages'; declare module 'fs-extra' { // eslint-disable-next-line import/prefer-default-export @@ -66,7 +73,7 @@ function checkForPlatformFailure(err: Error): void { ]; for (const errorStr of platformFailureStrings) { if (err.message.includes(errorStr)) { - throw new Error('platform-failure'); + throw new Error(PLATFORM_FAILURE); } } } @@ -76,7 +83,7 @@ function localName(branchName: string): string { } function throwBaseBranchValidationError(branchName: string): never { - const error = new Error('config-validation'); + const error = new Error(CONFIG_VALIDATION); error.validationError = 'baseBranch not found'; error.validationMessage = 'The following configured baseBranch could not be found: ' + branchName; @@ -145,7 +152,7 @@ export class Storage { 'fatal: ref refs/remotes/origin/HEAD is not a symbolic ref' ) ) { - throw new Error('empty'); + throw new Error(REPOSITORY_EMPTY); } throw err; } @@ -180,7 +187,7 @@ export class Storage { await this._git.clone(config.url, '.', ['--depth=2']); } catch (err) /* istanbul ignore next */ { logger.debug({ err }, 'git clone error'); - throw new Error('platform-failure'); + throw new Error(PLATFORM_FAILURE); } const cloneSeconds = Math.round(1 + 10 * convertHrtime(process.hrtime(cloneStart)).seconds) / @@ -202,7 +209,7 @@ export class Storage { } catch (err) /* istanbul ignore next */ { checkForPlatformFailure(err); if (err.message.includes('does not have any commits yet')) { - throw new Error('empty'); + throw new Error(REPOSITORY_EMPTY); } logger.warn({ err }, 'Cannot retrieve latest commit date'); } @@ -222,7 +229,7 @@ export class Storage { } catch (err) /* istanbul ignore next */ { checkForPlatformFailure(err); logger.debug({ err }, 'Error setting git config'); - throw new Error('temporary-error'); + throw new Error(REPOSITORY_TEMPORARY_ERROR); } } @@ -455,7 +462,7 @@ export class Storage { const exists = await this.branchExists(branchName); if (!exists) { logger.info({ branchName }, 'branch no longer exists - aborting'); - throw new Error('repository-changed'); + throw new Error(REPOSITORY_CHANGED); } } try { @@ -525,7 +532,7 @@ export class Storage { } catch (err) /* istanbul ignore next */ { checkForPlatformFailure(err); logger.debug({ err }, 'Error commiting files'); - throw new Error('repository-changed'); + throw new Error(REPOSITORY_CHANGED); } } diff --git a/lib/platform/github/gh-got-wrapper.ts b/lib/platform/github/gh-got-wrapper.ts index ff1e9bc20f375e8f5632574003b82225dc66ad51..5a91dfe9792dfadab8fa4dfaa4271de9e8a92c47 100644 --- a/lib/platform/github/gh-got-wrapper.ts +++ b/lib/platform/github/gh-got-wrapper.ts @@ -7,6 +7,13 @@ import got, { GotJSONOptions } from '../../util/got'; import { maskToken } from '../../util/mask'; import { GotApi, GotResponse } from '../common'; import { logger } from '../../logger'; +import { + PLATFORM_BAD_CREDENTIALS, + PLATFORM_INTEGRATION_UNAUTHORIZED, + PLATFORM_FAILURE, + PLATFORM_RATE_LIMIT_EXCEEDED, + REPOSITORY_CHANGED, +} from '../../constants/error-messages'; const hostType = 'github'; export const getHostType = (): string => hostType; @@ -42,22 +49,22 @@ export function dispatchError( err.code === 'EAI_AGAIN') ) { logger.info({ err }, 'GitHub failure: RequestError'); - throw new Error('platform-failure'); + throw new Error(PLATFORM_FAILURE); } if (err.name === 'ParseError') { logger.info({ err }, 'GitHub failure: ParseError'); - throw new Error('platform-failure'); + throw new Error(PLATFORM_FAILURE); } if (err.statusCode >= 500 && err.statusCode < 600) { logger.info({ err }, 'GitHub failure: 5xx'); - throw new Error('platform-failure'); + throw new Error(PLATFORM_FAILURE); } if ( err.statusCode === 403 && message.startsWith('You have triggered an abuse detection mechanism') ) { logger.info({ err }, 'GitHub failure: abuse detection'); - throw new Error('platform-failure'); + throw new Error(PLATFORM_RATE_LIMIT_EXCEEDED); } if (err.statusCode === 403 && message.includes('Upgrade to GitHub Pro')) { logger.debug({ path }, 'Endpoint needs paid GitHub plan'); @@ -65,7 +72,7 @@ export function dispatchError( } if (err.statusCode === 403 && message.includes('rate limit exceeded')) { logger.info({ err }, 'GitHub failure: rate limit'); - throw new Error('rate-limit-exceeded'); + throw new Error(PLATFORM_RATE_LIMIT_EXCEEDED); } if ( err.statusCode === 403 && @@ -75,7 +82,7 @@ export function dispatchError( { err }, 'GitHub failure: Resource not accessible by integration' ); - throw new Error('integration-unauthorized'); + throw new Error(PLATFORM_INTEGRATION_UNAUTHORIZED); } if (err.statusCode === 401 && message.includes('Bad credentials')) { const rateLimit = err.headers ? err.headers['x-ratelimit-limit'] : -1; @@ -87,9 +94,9 @@ export function dispatchError( 'GitHub failure: Bad credentials' ); if (rateLimit === '60') { - throw new Error('platform-failure'); + throw new Error(PLATFORM_FAILURE); } - throw new Error('bad-credentials'); + throw new Error(PLATFORM_BAD_CREDENTIALS); } if (err.statusCode === 422) { if ( @@ -101,9 +108,9 @@ export function dispatchError( err.body.errors && err.body.errors.find((e: any) => e.code === 'invalid') ) { - throw new Error('repository-changed'); + throw new Error(REPOSITORY_CHANGED); } - throw new Error('platform-failure'); + throw new Error(PLATFORM_FAILURE); } throw err; } diff --git a/lib/platform/github/index.ts b/lib/platform/github/index.ts index 9b762cf19032cc7fef34683562a884a221865982..372b3d40582119b82791f8fce141b9bb7725b43c 100644 --- a/lib/platform/github/index.ts +++ b/lib/platform/github/index.ts @@ -22,6 +22,19 @@ import { configFileNames } from '../../config/app-strings'; import { sanitize } from '../../util/sanitize'; import { smartTruncate } from '../utils/pr-body'; import { getGraphqlNodes } from './gh-graphql-wrapper'; +import { + PLATFORM_FAILURE, + REPOSITORY_ACCESS_FORBIDDEN, + REPOSITORY_ARCHIVED, + REPOSITORY_BLOCKED, + REPOSITORY_CANNOT_FORK, + REPOSITORY_CHANGED, + REPOSITORY_DISABLED, + REPOSITORY_EMPTY, + REPOSITORY_FORKED, + REPOSITORY_NOT_FOUND, + REPOSITORY_RENAMED, +} from '../../constants/error-messages'; const defaultConfigFile = configFileNames[0]; @@ -183,10 +196,10 @@ async function getBranchCommit(branchName: string): Promise<string> { } catch (err) /* istanbul ignore next */ { logger.debug({ err }, 'Error getting branch commit'); if (err.statusCode === 404) { - throw new Error('repository-changed'); + throw new Error(REPOSITORY_CHANGED); } if (err.statusCode === 409) { - throw new Error('empty'); + throw new Error(REPOSITORY_EMPTY); } throw err; } @@ -252,7 +265,7 @@ export async function initRepo({ throw new Error(); } } catch (err) { - throw new Error('fork'); + throw new Error(REPOSITORY_FORKED); } } if (res.body.full_name && res.body.full_name !== repository) { @@ -260,13 +273,13 @@ export async function initRepo({ { repository, this_repository: res.body.full_name }, 'Repository has been renamed' ); - throw new Error('renamed'); + throw new Error(REPOSITORY_RENAMED); } if (res.body.archived) { logger.info( 'Repository is archived - throwing error to abort renovation' ); - throw new Error('archived'); + throw new Error(REPOSITORY_ARCHIVED); } if (optimizeForDisabled) { let renovateConfig; @@ -283,7 +296,7 @@ export async function initRepo({ // Do nothing } if (renovateConfig && renovateConfig.enabled === false) { - throw new Error('disabled'); + throw new Error(REPOSITORY_DISABLED); } } const owner = res.body.owner.login; @@ -306,26 +319,29 @@ export async function initRepo({ } } catch (err) /* istanbul ignore next */ { logger.debug('Caught initRepo error'); - if (err.message === 'archived' || err.message === 'renamed') { + if ( + err.message === REPOSITORY_ARCHIVED || + err.message === REPOSITORY_RENAMED + ) { throw err; } if (err.statusCode === 403) { - throw new Error('forbidden'); + throw new Error(REPOSITORY_ACCESS_FORBIDDEN); } if (err.statusCode === 404) { - throw new Error('not-found'); + throw new Error(REPOSITORY_NOT_FOUND); } if (err.message.startsWith('Repository access blocked')) { - throw new Error('blocked'); + throw new Error(REPOSITORY_BLOCKED); } - if (err.message === 'fork') { + if (err.message === REPOSITORY_FORKED) { throw err; } - if (err.message === 'disabled') { + if (err.message === REPOSITORY_DISABLED) { throw err; } if (err.message === 'Response code 451 (Unavailable for Legal Reasons)') { - throw new Error('forbidden'); + throw new Error(REPOSITORY_ACCESS_FORBIDDEN); } logger.info({ err }, 'Unknown GitHub initRepo error'); throw err; @@ -358,7 +374,7 @@ export async function initRepo({ })).body.full_name; } catch (err) /* istanbul ignore next */ { logger.info({ err }, 'Error forking repository'); - throw new Error('cannot-fork'); + throw new Error(REPOSITORY_CANNOT_FORK); } if (existingRepos.includes(config.repository!)) { logger.info( @@ -384,14 +400,14 @@ export async function initRepo({ } ); } catch (err) /* istanbul ignore next */ { - if (err.message === 'platform-failure') { + if (err.message === PLATFORM_FAILURE) { throw err; } if ( err.statusCode === 422 && err.message.startsWith('Object does not exist') ) { - throw new Error('repository-changed'); + throw new Error(REPOSITORY_CHANGED); } } } else { @@ -1037,7 +1053,7 @@ export async function getBranchStatus( logger.info( 'Received 404 when checking branch status, assuming that branch has been deleted' ); - throw new Error('repository-changed'); + throw new Error(REPOSITORY_CHANGED); } logger.info('Unknown error when checking branch status'); throw err; @@ -1129,7 +1145,7 @@ export async function getBranchStatusCheck( } catch (err) /* istanbul ignore next */ { if (err.statusCode === 404) { logger.info('Commit not found when checking statuses'); - throw new Error('repository-changed'); + throw new Error(REPOSITORY_CHANGED); } throw err; } @@ -1170,7 +1186,7 @@ export async function setBranchStatus({ await getStatusCheck(branchName, false); } catch (err) /* istanbul ignore next */ { logger.info({ err }, 'Caught error setting branch status - aborting'); - throw new Error('repository-changed'); + throw new Error(REPOSITORY_CHANGED); } } @@ -1478,7 +1494,7 @@ async function getComments(issueNo: number): Promise<Comment[]> { } catch (err) /* istanbul ignore next */ { if (err.statusCode === 404) { logger.debug('404 respose when retrieving comments'); - throw new Error('platform-failure'); + throw new Error(PLATFORM_FAILURE); } throw err; } diff --git a/lib/platform/gitlab/gl-got-wrapper.ts b/lib/platform/gitlab/gl-got-wrapper.ts index 3488dcdb9df071c127ea665ccab85946cd781efb..5ac54d14bc5fc16c65b33a7abbfe2dca2955c9d3 100644 --- a/lib/platform/gitlab/gl-got-wrapper.ts +++ b/lib/platform/gitlab/gl-got-wrapper.ts @@ -3,6 +3,7 @@ import parseLinkHeader from 'parse-link-header'; import { GotApi, GotResponse } from '../common'; import got from '../../util/got'; import { logger } from '../../logger'; +import { PLATFORM_FAILURE } from '../../constants/error-messages'; const hostType = 'gitlab'; let baseUrl = 'https://gitlab.com/api/v4/'; @@ -32,7 +33,7 @@ async function get(path: string, options: any): Promise<GotResponse> { return res; } catch (err) /* istanbul ignore next */ { if (err.statusCode >= 500 && err.statusCode < 600) { - throw new Error('platform-failure'); + throw new Error(PLATFORM_FAILURE); } const platformFailureCodes = [ 'EAI_AGAIN', @@ -41,7 +42,7 @@ async function get(path: string, options: any): Promise<GotResponse> { 'UNABLE_TO_VERIFY_LEAF_SIGNATURE', ]; if (platformFailureCodes.includes(err.code)) { - throw new Error('platform-failure'); + throw new Error(PLATFORM_FAILURE); } throw err; } diff --git a/lib/platform/gitlab/index.ts b/lib/platform/gitlab/index.ts index b04600874c8a0934c04d41858c6febb12103ccbe..b10c7edf5d605f5908d51de565babc87f68ec2dc 100644 --- a/lib/platform/gitlab/index.ts +++ b/lib/platform/gitlab/index.ts @@ -21,6 +21,16 @@ import { logger } from '../../logger'; import { sanitize } from '../../util/sanitize'; import { smartTruncate } from '../utils/pr-body'; import { RenovateConfig } from '../../config'; +import { + PLATFORM_AUTHENTICATION_ERROR, + REPOSITORY_ACCESS_FORBIDDEN, + REPOSITORY_ARCHIVED, + REPOSITORY_CHANGED, + REPOSITORY_DISABLED, + REPOSITORY_EMPTY, + REPOSITORY_MIRRORED, + REPOSITORY_NOT_FOUND, +} from '../../constants/error-messages'; const defaultConfigFile = configFileNames[0]; let config: { @@ -134,28 +144,28 @@ export async function initRepo({ logger.info( 'Repository is archived - throwing error to abort renovation' ); - throw new Error('archived'); + throw new Error(REPOSITORY_ARCHIVED); } if (res.body.mirror) { logger.info( 'Repository is a mirror - throwing error to abort renovation' ); - throw new Error('mirror'); + throw new Error(REPOSITORY_MIRRORED); } if (res.body.repository_access_level === 'disabled') { logger.info( 'Repository portion of project is disabled - throwing error to abort renovation' ); - throw new Error('disabled'); + throw new Error(REPOSITORY_DISABLED); } if (res.body.merge_requests_access_level === 'disabled') { logger.info( 'MRs are disabled for the project - throwing error to abort renovation' ); - throw new Error('disabled'); + throw new Error(REPOSITORY_DISABLED); } if (res.body.default_branch === null || res.body.empty_repo) { - throw new Error('empty'); + throw new Error(REPOSITORY_EMPTY); } if (optimizeForDisabled) { let renovateConfig: RenovateConfig; @@ -172,7 +182,7 @@ export async function initRepo({ // Do nothing } if (renovateConfig && renovateConfig.enabled === false) { - throw new Error('disabled'); + throw new Error(REPOSITORY_DISABLED); } } config.defaultBranch = res.body.default_branch; @@ -211,18 +221,18 @@ export async function initRepo({ } catch (err) /* istanbul ignore next */ { logger.debug({ err }, 'Caught initRepo error'); if (err.message.includes('HEAD is not a symbolic ref')) { - throw new Error('empty'); + throw new Error(REPOSITORY_EMPTY); } if (['archived', 'empty'].includes(err.message)) { throw err; } if (err.statusCode === 403) { - throw new Error('forbidden'); + throw new Error(REPOSITORY_ACCESS_FORBIDDEN); } if (err.statusCode === 404) { - throw new Error('not-found'); + throw new Error(REPOSITORY_NOT_FOUND); } - if (err.message === 'disabled') { + if (err.message === REPOSITORY_DISABLED) { throw err; } logger.info({ err }, 'Unknown GitLab initRepo error'); @@ -300,7 +310,7 @@ export async function getBranchStatus( } if (!(await branchExists(branchName))) { - throw new Error('repository-changed'); + throw new Error(REPOSITORY_CHANGED); } const res = await getStatus(branchName); @@ -919,7 +929,7 @@ async function fetchPrList(): Promise<Pr[]> { } catch (err) /* istanbul ignore next */ { logger.debug({ err }, 'Error fetching PR list'); if (err.statusCode === 403) { - throw new Error('authentication-error'); + throw new Error(PLATFORM_AUTHENTICATION_ERROR); } throw err; } diff --git a/lib/platform/index.ts b/lib/platform/index.ts index 7d335490f0bd3e8a5346cec937a2564fcab6abd5..c9d0715eace26174b7bcf6d252d9fe38dd3117b2 100644 --- a/lib/platform/index.ts +++ b/lib/platform/index.ts @@ -5,6 +5,7 @@ import { logger } from '../logger'; import { Platform } from './common'; import { RenovateConfig } from '../config/common'; import { getOptions } from '../config/definitions'; +import { PLATFORM_NOT_FOUND } from '../constants/error-messages'; export * from './common'; @@ -16,7 +17,7 @@ let _platform: Platform; const handler: ProxyHandler<Platform> = { get(_target: Platform, prop: keyof Platform) { - if (!_platform) throw new Error(`platform-not-found`); + if (!_platform) throw new Error(PLATFORM_NOT_FOUND); // TODO: add more validation diff --git a/lib/util/regex.ts b/lib/util/regex.ts index 41dfce98f1ba292eaa95bf964c1bbefb3da29564..7cc415c653ae2fa54b3acffe30e5b2690f740232 100644 --- a/lib/util/regex.ts +++ b/lib/util/regex.ts @@ -1,4 +1,5 @@ import { logger } from '../logger'; +import { CONFIG_VALIDATION } from '../constants/error-messages'; let RegEx; @@ -18,7 +19,7 @@ export function regEx(pattern: string, flags?: string): RegExp { try { return new RegEx(pattern, flags); } catch (err) { - const error = new Error('config-validation'); + const error = new Error(CONFIG_VALIDATION); error.configFile = pattern; error.validationError = 'Invalid regular expression: ' + err.toString(); throw error; diff --git a/lib/versioning/regex/index.ts b/lib/versioning/regex/index.ts index 810ff33d581ff5fdbac312d520f2bee027598ae1..9a4a6f788216350a87f1c357a6f5b8953904ebce 100644 --- a/lib/versioning/regex/index.ts +++ b/lib/versioning/regex/index.ts @@ -2,6 +2,7 @@ import { compare, satisfies, ltr, minSatisfying, maxSatisfying } from 'semver'; import { VersioningApiConstructor } from '../common'; import { GenericVersion, GenericVersioningApi } from '../loose/generic'; import { regEx } from '../../util/regex'; +import { CONFIG_VALIDATION } from '../../constants/error-messages'; export interface RegExpVersion extends GenericVersion { /** prereleases are treated in the standard semver manner, if present */ @@ -47,7 +48,7 @@ export class RegExpVersioningApi extends GenericVersioningApi<RegExpVersion> { !new_config.includes('<minor>') && !new_config.includes('<patch>') ) { - const error = new Error('config-validation'); + const error = new Error(CONFIG_VALIDATION); error.configFile = new_config; error.validationError = 'regex versionScheme needs at least one major, minor or patch group defined'; diff --git a/lib/workers/branch/check-existing.ts b/lib/workers/branch/check-existing.ts index ece64e7a7ef886dcc159b884e3c4390a3ff78c12..8badbb1e413c448486418643d0061c8c8fdaea06 100644 --- a/lib/workers/branch/check-existing.ts +++ b/lib/workers/branch/check-existing.ts @@ -1,6 +1,7 @@ import { logger } from '../../logger'; import { RenovateConfig } from '../../config'; import { platform } from '../../platform'; +import { REPOSITORY_CHANGED } from '../../constants/error-messages'; /** TODO: Proper return type */ export async function prAlreadyExisted( @@ -20,7 +21,7 @@ export async function prAlreadyExisted( // istanbul ignore if if (prDetails.state === 'open') { logger.debug('PR reopened'); - throw new Error('repository-changed'); + throw new Error(REPOSITORY_CHANGED); } return pr; } diff --git a/lib/workers/branch/get-updated.ts b/lib/workers/branch/get-updated.ts index 3176cb84fd25b793b71eb91632df168eb6713ebd..a9e460ac3cceb469c373bb9783e78d7f9ad5a6fe 100644 --- a/lib/workers/branch/get-updated.ts +++ b/lib/workers/branch/get-updated.ts @@ -4,6 +4,7 @@ import { logger } from '../../logger'; import { get } from '../../manager'; import { RenovateConfig } from '../../config'; import { UpdateArtifactsConfig, ArtifactError } from '../../manager/common'; +import { WORKER_FILE_UPDATE_FAILED } from '../../constants/error-messages'; export interface PackageFilesResult { artifactErrors: ArtifactError[]; @@ -56,7 +57,7 @@ export async function getUpdatedPackageFiles( { existingContent, config: upgrade }, 'Error updating file' ); - throw new Error('update-failure'); + throw new Error(WORKER_FILE_UPDATE_FAILED); } if (newContent !== existingContent) { if (config.parentBranch) { diff --git a/lib/workers/branch/index.ts b/lib/workers/branch/index.ts index f66bdfac916bfcf2fb0dd86cb478901bd6951035..4929c1771be5f85cc8b356e4e7d6c398347d4b13 100644 --- a/lib/workers/branch/index.ts +++ b/lib/workers/branch/index.ts @@ -17,6 +17,18 @@ import { RenovateConfig } from '../../config'; import { platform } from '../../platform'; import { emojify } from '../../util/emoji'; import { BranchConfig } from '../common'; +import { + PLATFORM_AUTHENTICATION_ERROR, + PLATFORM_BAD_CREDENTIALS, + SYSTEM_INSUFFICIENT_DISK_SPACE, + PLATFORM_INTEGRATION_UNAUTHORIZED, + MANAGER_LOCKFILE_ERROR, + PLATFORM_RATE_LIMIT_EXCEEDED, + REPOSITORY_CHANGED, + WORKER_FILE_UPDATE_FAILED, + DATASOURCE_FAILURE, + PLATFORM_FAILURE, +} from '../../constants/error-messages'; export type ProcessBranchResult = | 'already-existed' @@ -146,7 +158,7 @@ export async function processBranch( logger.info( 'PR has been closed or merged since this run started - aborting' ); - throw new Error('repository-changed'); + throw new Error(REPOSITORY_CHANGED); } if ( branchPr.isModified || @@ -311,7 +323,7 @@ export async function processBranch( ); } else { logger.info('PR is less than a day old - raise error instead of PR'); - throw new Error('lockfile-error'); + throw new Error(MANAGER_LOCKFILE_ERROR); } } else { logger.debug('PR has no releaseTimestamp'); @@ -363,13 +375,13 @@ export async function processBranch( } } catch (err) /* istanbul ignore next */ { if (err.statusCode === 404) { - throw new Error('repository-changed'); + throw new Error(REPOSITORY_CHANGED); } - if (err.message === 'rate-limit-exceeded') { + if (err.message === PLATFORM_RATE_LIMIT_EXCEEDED) { logger.debug('Passing rate-limit-exceeded error up'); throw err; } - if (err.message === 'repository-changed') { + if (err.message === REPOSITORY_CHANGED) { logger.debug('Passing repository-changed error up'); throw err; } @@ -378,7 +390,7 @@ export async function processBranch( err.message.startsWith('remote: Invalid username or password') ) { logger.debug('Throwing bad credentials'); - throw new Error('bad-credentials'); + throw new Error(PLATFORM_BAD_CREDENTIALS); } if ( err.message && @@ -387,24 +399,24 @@ export async function processBranch( ) ) { logger.debug('Throwing bad credentials'); - throw new Error('bad-credentials'); + throw new Error(PLATFORM_BAD_CREDENTIALS); } - if (err.message === 'bad-credentials') { + if (err.message === PLATFORM_BAD_CREDENTIALS) { logger.debug('Passing bad-credentials error up'); throw err; } - if (err.message === 'integration-unauthorized') { + if (err.message === PLATFORM_INTEGRATION_UNAUTHORIZED) { logger.debug('Passing integration-unauthorized error up'); throw err; } - if (err.message === 'lockfile-error') { + if (err.message === MANAGER_LOCKFILE_ERROR) { logger.debug('Passing lockfile-error up'); throw err; } if (err.message && err.message.includes('space left on device')) { - throw new Error('disk-space'); + throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE); } - if (err.message.startsWith('disk-space')) { + if (err.message === SYSTEM_INSUFFICIENT_DISK_SPACE) { logger.debug('Passing disk-space error up'); throw err; } @@ -412,7 +424,7 @@ export async function processBranch( logger.debug('Passing 403 error up'); throw err; } - if (err.message === 'update-failure') { + if (err.message === WORKER_FILE_UPDATE_FAILED) { logger.warn('Error updating branch: update failure'); } else if (err.message.startsWith('bundler-')) { // we have already warned inside the bundler artifacts error handling, so just return @@ -421,11 +433,11 @@ export async function processBranch( err.messagee && err.message.includes('fatal: Authentication failed') ) { - throw new Error('authentication-failure'); + throw new Error(PLATFORM_AUTHENTICATION_ERROR); } else if ( - err.message !== 'registry-failure' && + err.message !== DATASOURCE_FAILURE && err.message !== 'disable-gitfs' && - err.message !== 'platform-failure' + err.message !== DATASOURCE_FAILURE ) { logger.error({ err }, `Error updating branch: ${err.message}`); } @@ -535,9 +547,9 @@ export async function processBranch( } catch (err) /* istanbul ignore next */ { if ( [ - 'rate-limit-exceeded', - 'platform-failure', - 'repository-changed', + PLATFORM_RATE_LIMIT_EXCEEDED, + PLATFORM_FAILURE, + REPOSITORY_CHANGED, ].includes(err.message) ) { logger.debug('Passing PR error up'); diff --git a/lib/workers/pr/index.ts b/lib/workers/pr/index.ts index 0ab179e0fd7c12ae46d0f7cd3b189c9b7137ecaf..d5fb7d56111b00d9b7976e87d18eb86a3bd8ee40 100644 --- a/lib/workers/pr/index.ts +++ b/lib/workers/pr/index.ts @@ -4,6 +4,12 @@ import { getChangeLogJSON } from './changelog'; import { getPrBody } from './body'; import { platform, BranchStatus, Pr } from '../../platform'; import { BranchConfig } from '../common'; +import { + PLATFORM_INTEGRATION_UNAUTHORIZED, + PLATFORM_FAILURE, + PLATFORM_RATE_LIMIT_EXCEEDED, + REPOSITORY_CHANGED, +} from '../../constants/error-messages'; function noWhitespace(input: string): string { return input.replace(/\r?\n|\r|\s/g, ''); @@ -378,10 +384,10 @@ export async function ensurePr( } catch (err) { // istanbul ignore if if ( - err.message === 'repository-changed' || - err.message === 'rate-limit-exceeded' || - err.message === 'platform-failure' || - err.message === 'integration-unauthorized' + err.message === REPOSITORY_CHANGED || + err.message === PLATFORM_RATE_LIMIT_EXCEEDED || + err.message === PLATFORM_FAILURE || + err.message === PLATFORM_INTEGRATION_UNAUTHORIZED ) { logger.debug('Passing error up'); throw err; diff --git a/lib/workers/repository/configured.ts b/lib/workers/repository/configured.ts index 021a262e60b7898d8ed20154e69d19ea9a532e67..201f7f96a9773005386b85fa82d94aac054254c8 100644 --- a/lib/workers/repository/configured.ts +++ b/lib/workers/repository/configured.ts @@ -1,10 +1,14 @@ +import { + REPOSITORY_DISABLED, + REPOSITORY_FORKED, +} from '../../constants/error-messages'; import { RenovateConfig } from '../../config'; export function checkIfConfigured(config: RenovateConfig): void { if (config.enabled === false) { - throw new Error('disabled'); + throw new Error(REPOSITORY_DISABLED); } if (config.isFork && !config.includeForks) { - throw new Error('fork'); + throw new Error(REPOSITORY_FORKED); } } diff --git a/lib/workers/repository/error.ts b/lib/workers/repository/error.ts index 5882d7727eacc505f277a82a53713127342eb71e..9b6a24e8d53cecb36dfe361addd3a16e9ffb0068 100644 --- a/lib/workers/repository/error.ts +++ b/lib/workers/repository/error.ts @@ -2,125 +2,153 @@ import { logger } from '../../logger'; import { raiseConfigWarningIssue } from './error-config'; import { RenovateConfig } from '../../config'; +import { + CONFIG_VALIDATION, + DATASOURCE_FAILURE, + MANAGER_LOCKFILE_ERROR, + MANAGER_NO_PACKAGE_FILES, + PLATFORM_AUTHENTICATION_ERROR, + PLATFORM_BAD_CREDENTIALS, + PLATFORM_FAILURE, + PLATFORM_INTEGRATION_UNAUTHORIZED, + PLATFORM_RATE_LIMIT_EXCEEDED, + REPOSITORY_ACCESS_FORBIDDEN, + REPOSITORY_ARCHIVED, + REPOSITORY_BLOCKED, + REPOSITORY_CANNOT_FORK, + REPOSITORY_CHANGED, + REPOSITORY_DISABLED, + REPOSITORY_EMPTY, + REPOSITORY_FORKED, + REPOSITORY_MIRRORED, + REPOSITORY_NO_VULNERABILITY, + REPOSITORY_NOT_FOUND, + REPOSITORY_RENAMED, + REPOSITORY_TEMPORARY_ERROR, + REPOSITORY_UNINITIATED, + SYSTEM_INSUFFICIENT_DISK_SPACE, + UNKNOWN_ERROR, +} from '../../constants/error-messages'; + export default async function handleError( config: RenovateConfig, err: Error ): Promise<string> { - if (err.message === 'uninitiated') { + if (err.message === REPOSITORY_UNINITIATED) { logger.info('Repository is uninitiated - skipping'); delete config.branchList; // eslint-disable-line no-param-reassign return err.message; } - if (err.message === 'empty') { + if (err.message === REPOSITORY_EMPTY) { logger.info('Repository is empty - skipping'); delete config.branchList; // eslint-disable-line no-param-reassign return err.message; } - if (err.message === 'disabled') { + if (err.message === REPOSITORY_DISABLED) { logger.info('Repository is disabled - skipping'); return err.message; } - if (err.message === 'archived') { + if (err.message === REPOSITORY_ARCHIVED) { logger.info('Repository is archived - skipping'); delete config.branchList; // eslint-disable-line no-param-reassign return err.message; } - if (err.message === 'mirror') { + if (err.message === REPOSITORY_MIRRORED) { logger.info('Repository is a mirror - skipping'); delete config.branchList; // eslint-disable-line no-param-reassign return err.message; } - if (err.message === 'renamed') { + if (err.message === REPOSITORY_RENAMED) { logger.info('Repository has been renamed - skipping'); delete config.branchList; // eslint-disable-line no-param-reassign return err.message; } - if (err.message === 'blocked') { + if (err.message === REPOSITORY_BLOCKED) { delete config.branchList; // eslint-disable-line no-param-reassign logger.info('Repository is blocked - skipping'); return err.message; } - if (err.message === 'forbidden') { + if (err.message === REPOSITORY_ACCESS_FORBIDDEN) { delete config.branchList; // eslint-disable-line no-param-reassign logger.info('Repository is forbidden'); return err.message; } - if (err.message === 'not-found') { + if (err.message === REPOSITORY_NOT_FOUND) { delete config.branchList; // eslint-disable-line no-param-reassign logger.error('Repository is not found'); return err.message; } - if (err.message === 'fork') { + if (err.message === REPOSITORY_FORKED) { logger.info('Repository is a fork and not manually configured - skipping'); return err.message; } - if (err.message === 'cannot-fork') { + if (err.message === REPOSITORY_CANNOT_FORK) { logger.info('Cannot fork repository - skipping'); return err.message; } - if (err.message === 'no-package-files') { + if (err.message === MANAGER_NO_PACKAGE_FILES) { logger.info('Repository has no package files - skipping'); return err.message; } - if (err.message === 'no-vulnerability-alerts') { + if (err.message === REPOSITORY_NO_VULNERABILITY) { logger.info('Repository has no vulnerability alerts - skipping'); return err.message; } - if (err.message === 'repository-changed') { + if (err.message === REPOSITORY_CHANGED) { logger.info('Repository has changed during renovation - aborting'); delete config.branchList; // eslint-disable-line no-param-reassign return err.message; } - if (err.message === 'config-validation') { + if (err.message === CONFIG_VALIDATION) { delete config.branchList; // eslint-disable-line no-param-reassign logger.info({ error: err }, 'Repository has invalid config'); await raiseConfigWarningIssue(config, err); return err.message; } - if (err.message === 'registry-failure') { + if (err.message === DATASOURCE_FAILURE) { logger.info('Registry error - skipping'); delete config.branchList; // eslint-disable-line no-param-reassign return err.message; } - if (err.message === 'platform-failure') { + if (err.message === PLATFORM_FAILURE) { logger.info('Platform error - skipping'); delete config.branchList; // eslint-disable-line no-param-reassign return err.message; } if ( err.message.includes('No space left on device') || - err.message === 'disk-space' + err.message === SYSTEM_INSUFFICIENT_DISK_SPACE ) { logger.error('Disk space error - skipping'); delete config.branchList; // eslint-disable-line no-param-reassign return err.message; } - if (err.message === 'rate-limit-exceeded') { + if (err.message === PLATFORM_RATE_LIMIT_EXCEEDED) { logger.warn('Rate limit exceeded - aborting'); delete config.branchList; // eslint-disable-line no-param-reassign return err.message; } - if (err.message === 'bad-credentials') { + if (err.message === PLATFORM_BAD_CREDENTIALS) { logger.warn('Bad credentials - aborting'); delete config.branchList; // eslint-disable-line no-param-reassign return err.message; } - if (err.message === 'integration-unauthorized') { + if (err.message === PLATFORM_INTEGRATION_UNAUTHORIZED) { logger.warn('Integration unauthorized - aborting'); delete config.branchList; // eslint-disable-line no-param-reassign return err.message; } - if (err.message === 'authentication-error') { + if (err.message === PLATFORM_AUTHENTICATION_ERROR) { logger.warn('Authentication error - aborting'); delete config.branchList; // eslint-disable-line no-param-reassign return err.message; } - if (err.message === 'temporary-error') { + if (err.message === REPOSITORY_TEMPORARY_ERROR) { logger.info('Temporary error - aborting'); delete config.branchList; // eslint-disable-line no-param-reassign return err.message; } - if (err.message === 'lockfile-error') { + if (err.message === MANAGER_LOCKFILE_ERROR) { delete config.branchList; // eslint-disable-line no-param-reassign logger.info('Lock file error - aborting'); delete config.branchList; // eslint-disable-line no-param-reassign @@ -130,7 +158,7 @@ export default async function handleError( logger.warn({ err }, 'Git error - aborting'); delete config.branchList; // eslint-disable-line no-param-reassign // rewrite this error - return 'platform-failure'; + return PLATFORM_FAILURE; } if ( err.message.includes('The remote end hung up unexpectedly') || @@ -139,11 +167,12 @@ export default async function handleError( logger.warn({ err }, 'Git error - aborting'); delete config.branchList; // eslint-disable-line no-param-reassign // rewrite this error - return 'platform-failure'; + return PLATFORM_FAILURE; } // Swallow this error so that other repositories can be processed logger.error({ err }, `Repository has unknown error`); // delete branchList to avoid cleaning up branches delete config.branchList; // eslint-disable-line no-param-reassign - return 'unknown-error'; + // eslint-disable-next-line no-undef + return UNKNOWN_ERROR; } diff --git a/lib/workers/repository/init/config.ts b/lib/workers/repository/init/config.ts index 06f5422cb90919d4e3cad172369effc85bba63c4..63f85d7919d506d275e827e70966b2a5a48a73a7 100644 --- a/lib/workers/repository/init/config.ts +++ b/lib/workers/repository/init/config.ts @@ -12,6 +12,10 @@ import { flattenPackageRules } from './flatten'; import * as hostRules from '../../../util/host-rules'; import { configFileNames } from '../../../config/app-strings'; import { platform } from '../../../platform'; +import { + CONFIG_VALIDATION, + DATASOURCE_FAILURE, +} from '../../../constants/error-messages'; // Check for repository config export async function mergeRenovateConfig( @@ -53,7 +57,7 @@ export async function mergeRenovateConfig( // istanbul ignore if if (renovateConfig === null) { logger.warn('Fetching renovate config returns null'); - throw new Error('registry-failure'); + throw new Error(DATASOURCE_FAILURE); } // istanbul ignore if if (!renovateConfig.length) { @@ -70,7 +74,7 @@ export async function mergeRenovateConfig( { renovateConfig }, 'Error parsing renovate config renovate.json5' ); - const error = new Error('config-validation'); + const error = new Error(CONFIG_VALIDATION); error.configFile = configFile; error.validationError = 'Invalid JSON5 (parsing failed)'; error.validationMessage = 'JSON5.parse error: ' + err.message; @@ -83,7 +87,7 @@ export async function mergeRenovateConfig( allowDuplicateKeys ); if (jsonValidationError) { - const error = new Error('config-validation'); + const error = new Error(CONFIG_VALIDATION); error.configFile = configFile; error.validationError = 'Invalid JSON (parsing failed)'; error.validationMessage = jsonValidationError; @@ -95,7 +99,7 @@ export async function mergeRenovateConfig( allowDuplicateKeys ); if (jsonValidationError) { - const error = new Error('config-validation'); + const error = new Error(CONFIG_VALIDATION); error.configFile = configFile; error.validationError = 'Duplicate keys in JSON'; error.validationMessage = JSON.stringify(jsonValidationError); @@ -105,7 +109,7 @@ export async function mergeRenovateConfig( renovateJson = JSON.parse(renovateConfig); } catch (err) /* istanbul ignore next */ { logger.debug({ renovateConfig }, 'Error parsing renovate config'); - const error = new Error('config-validation'); + const error = new Error(CONFIG_VALIDATION); error.configFile = configFile; error.validationError = 'Invalid JSON (parsing failed)'; error.validationMessage = 'JSON.parse error: ' + err.message; @@ -116,7 +120,7 @@ export async function mergeRenovateConfig( } const migratedConfig = await migrateAndValidate(config, renovateJson); if (migratedConfig.errors.length) { - const error = new Error('config-validation'); + const error = new Error(CONFIG_VALIDATION); error.configFile = configFile; error.validationError = 'The renovate configuration file contains some invalid settings'; diff --git a/lib/workers/repository/init/vulnerability.ts b/lib/workers/repository/init/vulnerability.ts index 6ccb90a5860cad558458a6f3180e59363523a5f6..d0555f8472a1c857461880dd146f7409fc68ccf8 100644 --- a/lib/workers/repository/init/vulnerability.ts +++ b/lib/workers/repository/init/vulnerability.ts @@ -2,6 +2,7 @@ import { logger } from '../../../logger'; import * as versioning from '../../../versioning'; import { platform } from '../../../platform'; import { RenovateConfig } from '../../../config'; +import { REPOSITORY_NO_VULNERABILITY } from '../../../constants/error-messages'; export async function detectVulnerabilityAlerts( input: RenovateConfig @@ -17,7 +18,7 @@ export async function detectVulnerabilityAlerts( if (!alerts.length) { logger.debug('No vulnerability alerts found'); if (input.vulnerabilityAlertsOnly) { - throw new Error('no-vulnerability-alerts'); + throw new Error(REPOSITORY_NO_VULNERABILITY); } return input; } diff --git a/lib/workers/repository/onboarding/branch/check.ts b/lib/workers/repository/onboarding/branch/check.ts index 01c69e55f44ce67abb075453745f8f33568a03e2..85b3cf9c4bfde8d2ad14dc0b92ceb0c35a5d6dac 100644 --- a/lib/workers/repository/onboarding/branch/check.ts +++ b/lib/workers/repository/onboarding/branch/check.ts @@ -2,6 +2,7 @@ import { logger } from '../../../../logger'; import { platform } from '../../../../platform'; import { configFileNames } from '../../../../config/app-strings'; import { RenovateConfig } from '../../../../config'; +import { REPOSITORY_DISABLED } from '../../../../constants/error-messages'; const findFile = async (fileName: string): Promise<boolean> => { logger.debug(`findFile(${fileName})`); @@ -60,7 +61,7 @@ export const isOnboarded = async (config: RenovateConfig): Promise<boolean> => { // If onboarding has been disabled and config files are required then the // repository has not been onboarded yet if (config.requireConfig && config.onboarding === false) { - throw new Error('disabled'); + throw new Error(REPOSITORY_DISABLED); } const pr = await closedPrExists(config); @@ -82,7 +83,7 @@ export const isOnboarded = async (config: RenovateConfig): Promise<boolean> => { `Renovate is disabled due to lack of config. If you wish to reenable it, you can either (a) commit a config file to your base branch, or (b) rename this closed PR to trigger a replacement onboarding PR.` ); } - throw new Error('disabled'); + throw new Error(REPOSITORY_DISABLED); }; export const onboardingPrExists = async ( diff --git a/lib/workers/repository/onboarding/branch/index.ts b/lib/workers/repository/onboarding/branch/index.ts index b441162f59515da27d8bbeb2f9926182438c15ac..bc49cde7f2c3d93ca1afc95c243b6b1cd5bc6974 100644 --- a/lib/workers/repository/onboarding/branch/index.ts +++ b/lib/workers/repository/onboarding/branch/index.ts @@ -5,6 +5,10 @@ import { rebaseOnboardingBranch } from './rebase'; import { isOnboarded, onboardingPrExists } from './check'; import { RenovateConfig } from '../../../../config'; import { platform } from '../../../../platform'; +import { + MANAGER_NO_PACKAGE_FILES, + REPOSITORY_FORKED, +} from '../../../../constants/error-messages'; export async function checkOnboardingBranch( config: RenovateConfig @@ -17,7 +21,7 @@ export async function checkOnboardingBranch( return { ...config, repoIsOnboarded }; } if (config.isFork && !config.includeForks) { - throw new Error('fork'); + throw new Error(REPOSITORY_FORKED); } logger.info('Repo is not onboarded'); if (await onboardingPrExists(config)) { @@ -26,7 +30,7 @@ export async function checkOnboardingBranch( } else { logger.debug('Onboarding PR does not exist'); if (Object.entries(await extractAllDependencies(config)).length === 0) { - throw new Error('no-package-files'); + throw new Error(MANAGER_NO_PACKAGE_FILES); } logger.info('Need to create onboarding PR'); await createOnboardingBranch(config); diff --git a/lib/workers/repository/process/lookup/filter.ts b/lib/workers/repository/process/lookup/filter.ts index 641d22abb9986a4ddf7581eb8f4ea4363c6b70b4..c83f207f366e7de04540d83ff441fd40b2fddd26 100644 --- a/lib/workers/repository/process/lookup/filter.ts +++ b/lib/workers/repository/process/lookup/filter.ts @@ -2,6 +2,7 @@ import * as semver from 'semver'; import { logger } from '../../../../logger'; import * as versioning from '../../../../versioning'; import { Release } from '../../../../datasource'; +import { CONFIG_VALIDATION } from '../../../../constants/error-messages'; export interface FilterConfig { allowedVersions?: string; @@ -66,7 +67,7 @@ export function filterVersions( semver.satisfies(semver.coerce(v), allowedVersions) ); } else { - const error = new Error('config-validation'); + const error = new Error(CONFIG_VALIDATION); error.configFile = 'config'; error.validationError = 'Invalid `allowedVersions`'; error.validationMessage = diff --git a/lib/workers/repository/result.ts b/lib/workers/repository/result.ts index 4a90fdeac176c7381986d78e574ebe0bdbd61b93..6db4f9022721f8c4c7ee5ca434511f1f84b5fe4b 100644 --- a/lib/workers/repository/result.ts +++ b/lib/workers/repository/result.ts @@ -1,7 +1,19 @@ import { RenovateConfig } from '../../config'; +import { + MANAGER_NO_PACKAGE_FILES, + REPOSITORY_ACCESS_FORBIDDEN, + REPOSITORY_ARCHIVED, + REPOSITORY_BLOCKED, + REPOSITORY_CANNOT_FORK, + REPOSITORY_DISABLED, + REPOSITORY_EMPTY, + REPOSITORY_FORKED, + REPOSITORY_MIRRORED, + REPOSITORY_RENAMED, + REPOSITORY_UNINITIATED, +} from '../../constants/error-messages'; type ProcessStatus = 'disabled' | 'enabled' | 'onboarding' | 'unknown'; - export interface ProcessResult { res: string; status: ProcessStatus; @@ -12,17 +24,17 @@ export function processResult( res: string ): ProcessResult { const disabledStatuses = [ - 'archived', - 'blocked', - 'cannot-fork', - 'disabled', - 'forbidden', - 'fork', - 'mirror', - 'no-package-files', - 'renamed', - 'uninitiated', - 'empty', + REPOSITORY_ARCHIVED, + REPOSITORY_BLOCKED, + REPOSITORY_CANNOT_FORK, + REPOSITORY_DISABLED, + REPOSITORY_ACCESS_FORBIDDEN, + REPOSITORY_FORKED, + REPOSITORY_MIRRORED, + MANAGER_NO_PACKAGE_FILES, + REPOSITORY_RENAMED, + REPOSITORY_UNINITIATED, + REPOSITORY_EMPTY, ]; let status: ProcessStatus; // istanbul ignore next diff --git a/test/datasource/docker.spec.ts b/test/datasource/docker.spec.ts index 342232ac9972d737329240787bdb835ac7470088..804fbbe2ef64fd93da8903d8473942508ad88259 100644 --- a/test/datasource/docker.spec.ts +++ b/test/datasource/docker.spec.ts @@ -4,6 +4,7 @@ import _got from '../../lib/util/got'; import * as docker from '../../lib/datasource/docker'; import { getPkgReleases } from '../../lib/datasource'; import * as _hostRules from '../../lib/util/host-rules'; +import { DATASOURCE_FAILURE } from '../../lib/constants/error-messages'; const got: any = _got; const hostRules: any = _hostRules; @@ -259,13 +260,13 @@ describe('api/docker', () => { got.mockRejectedValueOnce({ statusCode: 429 }); await expect( docker.getDigest({ lookupName: 'some-dep' }, 'latest') - ).rejects.toThrow(Error('registry-failure')); + ).rejects.toThrow(Error(DATASOURCE_FAILURE)); }); it('should throw error for 5xx', async () => { got.mockRejectedValueOnce({ statusCode: 503 }); await expect( docker.getDigest({ lookupName: 'some-dep' }, 'latest') - ).rejects.toThrow(Error('registry-failure')); + ).rejects.toThrow(Error(DATASOURCE_FAILURE)); }); }); describe('getPkgReleases', () => { diff --git a/test/datasource/github.spec.ts b/test/datasource/github.spec.ts index b830f9bc291cee9c236ae752b226bf176a696a17..6255bb249e03652bbc909526faa4d8b6e29ffb38 100644 --- a/test/datasource/github.spec.ts +++ b/test/datasource/github.spec.ts @@ -4,6 +4,7 @@ import * as datasource from '../../lib/datasource'; import * as github from '../../lib/datasource/github'; import _got from '../../lib/util/got'; import * as _hostRules from '../../lib/util/host-rules'; +import { PLATFORM_FAILURE } from '../../lib/constants/error-messages'; jest.mock('../../lib/platform/github/gh-got-wrapper'); jest.mock('../../lib/util/got'); @@ -65,10 +66,10 @@ describe('datasource/github', () => { describe('getPreset()', () => { it('passes up platform-failure', async () => { got.mockImplementationOnce(() => { - throw new Error('platform-failure'); + throw new Error(PLATFORM_FAILURE); }); await expect(github.getPreset('some/repo')).rejects.toThrow( - 'platform-failure' + PLATFORM_FAILURE ); }); it('tries default then renovate', async () => { diff --git a/test/datasource/hex.spec.ts b/test/datasource/hex.spec.ts index 60fed3c182154a7675c3aadc0ca80673686f7a0a..5d79d88fd5b8ec399096000a08a6709d2a12cae4 100644 --- a/test/datasource/hex.spec.ts +++ b/test/datasource/hex.spec.ts @@ -2,6 +2,7 @@ import fs from 'fs'; import _got from '../../lib/util/got'; import * as _hostRules from '../../lib/util/host-rules'; import { getPkgReleases } from '../../lib/datasource/hex'; +import { DATASOURCE_FAILURE } from '../../lib/constants/error-messages'; const got: any = _got; const hostRules: any = _hostRules; @@ -61,7 +62,7 @@ describe('datasource/hex', () => { ); await expect( getPkgReleases({ lookupName: 'some_crate' }) - ).rejects.toThrowError('registry-failure'); + ).rejects.toThrowError(DATASOURCE_FAILURE); }); it('throws for 5xx', async () => { got.mockImplementationOnce(() => @@ -71,7 +72,7 @@ describe('datasource/hex', () => { ); await expect( getPkgReleases({ lookupName: 'some_crate' }) - ).rejects.toThrowError('registry-failure'); + ).rejects.toThrowError(DATASOURCE_FAILURE); }); it('returns null for unknown error', async () => { got.mockImplementationOnce(() => { diff --git a/test/datasource/maven.spec.ts b/test/datasource/maven.spec.ts index 7581c3ab362d6180a41d470b491dd8fd8e71dc46..846143ae3425bc969ea969f7057e0a702bad1c7d 100644 --- a/test/datasource/maven.spec.ts +++ b/test/datasource/maven.spec.ts @@ -1,6 +1,7 @@ import nock from 'nock'; import fs from 'fs'; import * as datasource from '../../lib/datasource'; +import { DATASOURCE_FAILURE } from '../../lib/constants/error-messages'; const hostRules = require('../../lib/util/host-rules'); @@ -176,7 +177,7 @@ describe('datasource/maven', () => { lookupName: 'org:artifact', registryUrls: ['http://central.maven.org/maven2/'], }) - ).rejects.toThrow(Error('registry-failure')); + ).rejects.toThrow(Error(DATASOURCE_FAILURE)); }); it('should return all versions of a specific library if a repository fails because invalid protocol', async () => { diff --git a/test/datasource/npm/index.spec.ts b/test/datasource/npm/index.spec.ts index 25cd89fadeffdf751660422d73acfdea9bc3bfd3..4d553b4cbb89bda3a600b5776b1616268316bab9 100644 --- a/test/datasource/npm/index.spec.ts +++ b/test/datasource/npm/index.spec.ts @@ -2,6 +2,7 @@ import _registryAuthToken from 'registry-auth-token'; import nock from 'nock'; import moment from 'moment'; import * as npm from '../../../lib/datasource/npm'; +import { DATASOURCE_FAILURE } from '../../../lib/constants/error-messages'; jest.mock('registry-auth-token'); jest.mock('delay'); @@ -328,7 +329,7 @@ describe('api/npm', () => { .get('/foobar') .reply(503); await expect(npm.getPkgReleases({ lookupName: 'foobar' })).rejects.toThrow( - Error('registry-failure') + Error(DATASOURCE_FAILURE) ); }); it('should throw error for 408', async () => { @@ -336,7 +337,7 @@ describe('api/npm', () => { .get('/foobar') .reply(408); await expect(npm.getPkgReleases({ lookupName: 'foobar' })).rejects.toThrow( - Error('registry-failure') + Error(DATASOURCE_FAILURE) ); }); it('should throw error for others', async () => { diff --git a/test/platform/azure/index.spec.ts b/test/platform/azure/index.spec.ts index 86c8c20ca885c6254f3632144e46ba8cb1bee051..cd5add0e2eea2ded54952c8fc968380d5f187c32 100644 --- a/test/platform/azure/index.spec.ts +++ b/test/platform/azure/index.spec.ts @@ -1,6 +1,7 @@ import is from '@sindresorhus/is'; import * as _hostRules from '../../../lib/util/host-rules'; import { RepoParams } from '../../../lib/platform/common'; +import { REPOSITORY_DISABLED } from '../../../lib/constants/error-messages'; describe('platform/azure', () => { let hostRules: jest.Mocked<typeof _hostRules>; @@ -187,7 +188,7 @@ describe('platform/azure', () => { azureHelper.getFile.mockResolvedValueOnce('{ "enabled": false }'); await expect( initRepo({ repository: 'some-repo', optimizeForDisabled: true }) - ).rejects.toThrow('disabled'); + ).rejects.toThrow(REPOSITORY_DISABLED); }); }); diff --git a/test/platform/bitbucket-server/index.spec.ts b/test/platform/bitbucket-server/index.spec.ts index 16c24a8f5c69e99b22ce8e45f30bc3a935e5bfd8..6b08d695f0d01a20027bc2be0b0853ce37516ca5 100644 --- a/test/platform/bitbucket-server/index.spec.ts +++ b/test/platform/bitbucket-server/index.spec.ts @@ -1,6 +1,11 @@ import responses from './_fixtures/responses'; import { GotApi, RepoParams } from '../../../lib/platform/common'; import { Storage } from '../../../lib/platform/git/storage'; +import { + REPOSITORY_CHANGED, + REPOSITORY_DISABLED, + REPOSITORY_NOT_FOUND, +} from '../../../lib/constants/error-messages'; type BbsApi = typeof import('../../../lib/platform/bitbucket-server'); @@ -147,7 +152,7 @@ describe('platform/bitbucket-server', () => { body: { isLastPage: true, lines: ['{ "enabled": false }'] }, } as any); await expect(initRepo({ optimizeForDisabled: true })).rejects.toThrow( - 'disabled' + REPOSITORY_DISABLED ); }); }); @@ -268,10 +273,10 @@ describe('platform/bitbucket-server', () => { await expect( bitbucket.addReviewers(null as any, ['name']) - ).rejects.toThrow('not-found'); + ).rejects.toThrow(REPOSITORY_NOT_FOUND); await expect(bitbucket.addReviewers(4, ['name'])).rejects.toThrow( - 'not-found' + REPOSITORY_NOT_FOUND ); api.put.mockReturnValueOnce( Promise.reject({ @@ -279,7 +284,7 @@ describe('platform/bitbucket-server', () => { }) ); await expect(bitbucket.addReviewers(5, ['name'])).rejects.toThrow( - 'not-found' + REPOSITORY_NOT_FOUND ); expect(api.get.mock.calls).toMatchSnapshot(); @@ -295,7 +300,7 @@ describe('platform/bitbucket-server', () => { }) ); await expect(bitbucket.addReviewers(5, ['name'])).rejects.toThrow( - 'repository-changed' + REPOSITORY_CHANGED ); expect(api.get.mock.calls).toMatchSnapshot(); expect(api.put.mock.calls).toMatchSnapshot(); @@ -578,10 +583,10 @@ describe('platform/bitbucket-server', () => { await expect( bitbucket.updatePr(null as any, 'title', 'body') - ).rejects.toThrow('not-found'); + ).rejects.toThrow(REPOSITORY_NOT_FOUND); await expect(bitbucket.updatePr(4, 'title', 'body')).rejects.toThrow( - 'not-found' + REPOSITORY_NOT_FOUND ); api.put.mockReturnValueOnce( Promise.reject({ @@ -589,7 +594,7 @@ describe('platform/bitbucket-server', () => { }) ); await expect(bitbucket.updatePr(5, 'title', 'body')).rejects.toThrow( - 'not-found' + REPOSITORY_NOT_FOUND ); expect(api.get.mock.calls).toMatchSnapshot(); @@ -605,7 +610,7 @@ describe('platform/bitbucket-server', () => { }) ); await expect(bitbucket.updatePr(5, 'title', 'body')).rejects.toThrow( - 'repository-changed' + REPOSITORY_CHANGED ); expect(api.get.mock.calls).toMatchSnapshot(); expect(api.put.mock.calls).toMatchSnapshot(); @@ -642,9 +647,9 @@ describe('platform/bitbucket-server', () => { await expect( bitbucket.mergePr(null as any, 'branch') - ).rejects.toThrow('not-found'); + ).rejects.toThrow(REPOSITORY_NOT_FOUND); await expect(bitbucket.mergePr(4, 'branch')).rejects.toThrow( - 'not-found' + REPOSITORY_NOT_FOUND ); api.post.mockReturnValueOnce( @@ -654,7 +659,7 @@ describe('platform/bitbucket-server', () => { ); await expect(bitbucket.mergePr(5, 'branch')).rejects.toThrow( - 'not-found' + REPOSITORY_NOT_FOUND ); expect(api.get.mock.calls).toMatchSnapshot(); expect(api.post.mock.calls).toMatchSnapshot(); @@ -817,7 +822,7 @@ Followed by some information. await initRepo(); await expect( bitbucket.getBranchStatus('somebranch', true) - ).rejects.toThrow('repository-changed'); + ).rejects.toThrow(REPOSITORY_CHANGED); }); }); diff --git a/test/platform/bitbucket/index.spec.ts b/test/platform/bitbucket/index.spec.ts index 9e73e4d28486103f638a892d9c143f2167d65047..39f97af35be112f4614ba49224817d0b509cb7d7 100644 --- a/test/platform/bitbucket/index.spec.ts +++ b/test/platform/bitbucket/index.spec.ts @@ -1,6 +1,7 @@ import URL from 'url'; import responses from './_fixtures/responses'; import { GotApi, RepoParams } from '../../../lib/platform/common'; +import { REPOSITORY_DISABLED } from '../../../lib/constants/error-messages'; describe('platform/bitbucket', () => { let bitbucket: typeof import('../../../lib/platform/bitbucket'); @@ -127,7 +128,7 @@ describe('platform/bitbucket', () => { expect.assertions(1); await expect( initRepo({ repository: 'some/empty', optimizeForDisabled: true }) - ).rejects.toThrow('disabled'); + ).rejects.toThrow(REPOSITORY_DISABLED); }); }); diff --git a/test/platform/github/gh-got-wrapper.spec.ts b/test/platform/github/gh-got-wrapper.spec.ts index c618d75223464101448892f77c4acc14ee8efc23..97b383aad52f89f35f0d8f451c5288290d322acc 100644 --- a/test/platform/github/gh-got-wrapper.spec.ts +++ b/test/platform/github/gh-got-wrapper.spec.ts @@ -2,6 +2,10 @@ import delay from 'delay'; import { Response } from 'got'; import _got from '../../../lib/util/got'; import { api } from '../../../lib/platform/github/gh-got-wrapper'; +import { + PLATFORM_BAD_CREDENTIALS, + PLATFORM_RATE_LIMIT_EXCEEDED, +} from '../../../lib/constants/error-messages'; jest.mock('../../../lib/util/got'); jest.mock('delay'); @@ -104,7 +108,7 @@ describe('platform/gh-got-wrapper', () => { ); const e = await getError(); expect(e).toBeDefined(); - expect(e.message).toEqual('bad-credentials'); + expect(e.message).toEqual(PLATFORM_BAD_CREDENTIALS); }); it('should throw platform failure', async () => { got.mockImplementationOnce(() => @@ -185,7 +189,7 @@ describe('platform/gh-got-wrapper', () => { got.mockRejectedValueOnce(gotErr); const e = await getError(); expect(e).toBeDefined(); - expect(e.message).toEqual('platform-failure'); + expect(e.message).toEqual(PLATFORM_RATE_LIMIT_EXCEEDED); }); it('should throw on repository change', async () => { const gotErr = { diff --git a/test/platform/github/index.spec.ts b/test/platform/github/index.spec.ts index aa10e5c0ef9623c82b70395d2c37195da732826a..a56630f95476293ca654717a4b3eb632485ccf5d 100644 --- a/test/platform/github/index.spec.ts +++ b/test/platform/github/index.spec.ts @@ -1,5 +1,10 @@ import fs from 'fs-extra'; import { GotApi, GotResponse } from '../../../lib/platform/common'; +import { + REPOSITORY_DISABLED, + REPOSITORY_NOT_FOUND, + REPOSITORY_RENAMED, +} from '../../../lib/constants/error-messages'; describe('platform/github', () => { let github: typeof import('../../../lib/platform/github'); @@ -220,7 +225,7 @@ describe('platform/github', () => { repository: 'some/repo', optimizeForDisabled: true, } as any) - ).rejects.toThrow('disabled'); + ).rejects.toThrow(REPOSITORY_DISABLED); }); it('should rebase', async () => { function squashInitRepo(args: any) { @@ -443,7 +448,7 @@ describe('platform/github', () => { github.initRepo({ repository: 'some/repo', } as any) - ).rejects.toThrow('not-found'); + ).rejects.toThrow(REPOSITORY_NOT_FOUND); }); it('should throw error if renamed', async () => { api.get.mockReturnValueOnce({ @@ -458,7 +463,7 @@ describe('platform/github', () => { includeForks: true, repository: 'some/repo', } as any) - ).rejects.toThrow('renamed'); + ).rejects.toThrow(REPOSITORY_RENAMED); }); }); describe('getRepoForceRebase', () => { diff --git a/test/platform/gitlab/index.spec.ts b/test/platform/gitlab/index.spec.ts index 3ada3d3124104f5219d4884049b67911023fea85..254171e3db0c4dea221e360e73d65d035bdfff7e 100644 --- a/test/platform/gitlab/index.spec.ts +++ b/test/platform/gitlab/index.spec.ts @@ -1,4 +1,11 @@ import * as _hostRules from '../../../lib/util/host-rules'; +import { + REPOSITORY_ARCHIVED, + REPOSITORY_CHANGED, + REPOSITORY_DISABLED, + REPOSITORY_EMPTY, + REPOSITORY_MIRRORED, +} from '../../../lib/constants/error-messages'; describe('platform/gitlab', () => { let gitlab: typeof import('../../../lib/platform/gitlab'); @@ -194,7 +201,7 @@ describe('platform/gitlab', () => { localDir: '', optimizeForDisabled: true, }) - ).rejects.toThrow(Error('disabled')); + ).rejects.toThrow(Error(REPOSITORY_DISABLED)); }); it(`should escape all forward slashes in project names`, async () => { api.get.mockReturnValue({ body: [] } as any); @@ -221,7 +228,7 @@ describe('platform/gitlab', () => { localDir: '', optimizeForDisabled: false, }) - ).rejects.toThrow(Error('archived')); + ).rejects.toThrow(Error(REPOSITORY_ARCHIVED)); }); it('should throw an error if repository is a mirror', async () => { api.get.mockReturnValue({ body: { mirror: true } } as any); @@ -231,7 +238,7 @@ describe('platform/gitlab', () => { localDir: '', optimizeForDisabled: false, }) - ).rejects.toThrow(Error('mirror')); + ).rejects.toThrow(Error(REPOSITORY_MIRRORED)); }); it('should throw an error if repository access is disabled', async () => { api.get.mockReturnValue({ @@ -243,7 +250,7 @@ describe('platform/gitlab', () => { localDir: '', optimizeForDisabled: false, }) - ).rejects.toThrow(Error('disabled')); + ).rejects.toThrow(Error(REPOSITORY_DISABLED)); }); it('should throw an error if MRs are disabled', async () => { api.get.mockReturnValue({ @@ -255,7 +262,7 @@ describe('platform/gitlab', () => { localDir: '', optimizeForDisabled: false, }) - ).rejects.toThrow(Error('disabled')); + ).rejects.toThrow(Error(REPOSITORY_DISABLED)); }); it('should throw an error if repository has empty_repo property', async () => { api.get.mockReturnValue({ body: { empty_repo: true } } as any); @@ -265,7 +272,7 @@ describe('platform/gitlab', () => { localDir: '', optimizeForDisabled: false, }) - ).rejects.toThrow(Error('empty')); + ).rejects.toThrow(Error(REPOSITORY_EMPTY)); }); it('should throw an error if repository is empty', async () => { api.get.mockReturnValue({ body: { default_branch: null } } as any); @@ -275,7 +282,7 @@ describe('platform/gitlab', () => { localDir: '', optimizeForDisabled: false, }) - ).rejects.toThrow(Error('empty')); + ).rejects.toThrow(Error(REPOSITORY_EMPTY)); }); it('should fall back if http_url_to_repo is empty', async () => { api.get.mockReturnValue({ @@ -454,7 +461,7 @@ describe('platform/gitlab', () => { })); await initRepo(); await expect(gitlab.getBranchStatus('somebranch', [])).rejects.toThrow( - 'repository-changed' + REPOSITORY_CHANGED ); }); }); diff --git a/test/platform/index.spec.ts b/test/platform/index.spec.ts index 33d7b8d5fc48cab3b69c3afb784c0fc0f856309f..22fd26ac57f5b7fee85e18c49c1602f2b63143c1 100644 --- a/test/platform/index.spec.ts +++ b/test/platform/index.spec.ts @@ -3,6 +3,7 @@ import * as gitlab from '../../lib/platform/gitlab'; import * as azure from '../../lib/platform/azure'; import * as bitbucket from '../../lib/platform/bitbucket'; import * as bitbucketServer from '../../lib/platform/bitbucket-server'; +import { PLATFORM_NOT_FOUND } from '../../lib/constants/error-messages'; import * as platform from '../../lib/platform'; @@ -14,7 +15,7 @@ describe('platform', () => { }); it('throws if no platform', () => { expect(() => platform.platform.initPlatform({})).toThrow( - 'platform-not-found' + PLATFORM_NOT_FOUND ); }); it('throws if wrong platform', async () => { diff --git a/test/util/regex.spec.ts b/test/util/regex.spec.ts index 64ea780e9c905464f88bd2e63256aac51da4e1cf..3ad5a9ea356d631fb119ea92c9ff9f6b525e6962 100644 --- a/test/util/regex.spec.ts +++ b/test/util/regex.spec.ts @@ -1,5 +1,6 @@ import RE2 from 're2'; import { regEx } from '../../lib/util/regex'; +import { CONFIG_VALIDATION } from '../../lib/constants/error-messages'; describe('util/regex', () => { beforeEach(() => { @@ -10,7 +11,7 @@ describe('util/regex', () => { expect(regEx('foo')).toBeInstanceOf(RE2); }); it('throws unsafe 2', () => { - expect(() => regEx(`x++`)).toThrow('config-validation'); + expect(() => regEx(`x++`)).toThrow(CONFIG_VALIDATION); }); it('Falls back to RegExp', () => { diff --git a/test/versioning/regex.spec.ts b/test/versioning/regex.spec.ts index 5cc01583ea229d2c772547035803377fb49af2c9..c1bf66f8b6939439e45bb2f2f87470a2866e8794 100644 --- a/test/versioning/regex.spec.ts +++ b/test/versioning/regex.spec.ts @@ -1,4 +1,5 @@ import { get, VersioningApi } from '../../lib/versioning'; +import { CONFIG_VALIDATION } from '../../lib/constants/error-messages'; describe('regex', () => { const regex: VersioningApi = get( @@ -16,7 +17,7 @@ describe('regex', () => { '^(?<major>\\d+)?(?<=y)x$', ]) { it(re, () => { - expect(() => get(`regex:${re}`)).toThrow('config-validation'); + expect(() => get(`regex:${re}`)).toThrow(CONFIG_VALIDATION); }); } }); diff --git a/test/workers/branch/index.spec.ts b/test/workers/branch/index.spec.ts index 0995ca95317fb72464378ce2ddc8cadfb0957e04..7b758d0171e0f9b79c8890fcd32c9226bde19fda 100644 --- a/test/workers/branch/index.spec.ts +++ b/test/workers/branch/index.spec.ts @@ -10,6 +10,10 @@ import * as _prWorker from '../../../lib/workers/pr'; import * as _getUpdated from '../../../lib/workers/branch/get-updated'; import { defaultConfig, platform, mocked } from '../../util'; import { BranchConfig } from '../../../lib/workers/common'; +import { + MANAGER_LOCKFILE_ERROR, + REPOSITORY_CHANGED, +} from '../../../lib/constants/error-messages'; jest.mock('../../../lib/workers/branch/get-updated'); jest.mock('../../../lib/workers/branch/schedule'); @@ -151,7 +155,7 @@ describe('workers/branch', () => { isModified: true, } as never); await expect(branchWorker.processBranch(config)).rejects.toThrow( - /repository-changed/ + REPOSITORY_CHANGED ); }); it('does not skip branch if edited PR found with rebaseLabel', async () => { @@ -357,7 +361,7 @@ describe('workers/branch', () => { prWorker.checkAutoMerge.mockResolvedValueOnce(true); config.releaseTimestamp = new Date().toISOString(); await expect(branchWorker.processBranch(config)).rejects.toThrow( - Error('lockfile-error') + Error(MANAGER_LOCKFILE_ERROR) ); }); it('ensures PR and adds lock file error comment recreate closed', async () => { diff --git a/test/workers/repository/error-config.spec.ts b/test/workers/repository/error-config.spec.ts index fab8668426de047818a28775d7a0b5e832fb7ff0..b9b6d831dde449d9c7a2e4749469a99fa7fe2451 100644 --- a/test/workers/repository/error-config.spec.ts +++ b/test/workers/repository/error-config.spec.ts @@ -1,5 +1,5 @@ import { mock } from 'jest-mock-extended'; - +import { CONFIG_VALIDATION } from '../../../lib/constants/error-messages'; import { raiseConfigWarningIssue } from '../../../lib/workers/repository/error-config'; import { RenovateConfig, getConfig, platform } from '../../util'; import { Pr } from '../../../lib/platform'; @@ -15,7 +15,7 @@ beforeEach(() => { describe('workers/repository/error-config', () => { describe('raiseConfigWarningIssue()', () => { it('creates issues', async () => { - const error = new Error('config-validation'); + const error = new Error(CONFIG_VALIDATION); error.configFile = 'package.json'; error.validationMessage = 'some-message'; platform.ensureIssue.mockResolvedValueOnce('created'); @@ -23,7 +23,7 @@ describe('workers/repository/error-config', () => { expect(res).toBeUndefined(); }); it('creates issues (dryRun)', async () => { - const error = new Error('config-validation'); + const error = new Error(CONFIG_VALIDATION); error.configFile = 'package.json'; error.validationMessage = 'some-message'; platform.ensureIssue.mockResolvedValueOnce('created'); @@ -34,7 +34,7 @@ describe('workers/repository/error-config', () => { expect(res).toBeUndefined(); }); it('handles onboarding', async () => { - const error = new Error('config-validation'); + const error = new Error(CONFIG_VALIDATION); error.configFile = 'package.json'; error.validationMessage = 'some-message'; platform.getBranchPr.mockResolvedValue({ @@ -46,7 +46,7 @@ describe('workers/repository/error-config', () => { expect(res).toBeUndefined(); }); it('handles onboarding (dryRun)', async () => { - const error = new Error('config-validation'); + const error = new Error(CONFIG_VALIDATION); error.configFile = 'package.json'; error.validationMessage = 'some-message'; platform.getBranchPr.mockResolvedValue({ diff --git a/test/workers/repository/error.spec.ts b/test/workers/repository/error.spec.ts index 0c72cb47318a90771124997266e21e313e7569c9..5ab5cae31fbeb4096db7be45b2204c0c2a460b55 100644 --- a/test/workers/repository/error.spec.ts +++ b/test/workers/repository/error.spec.ts @@ -1,4 +1,31 @@ import handleError from '../../../lib/workers/repository/error'; +import { + CONFIG_VALIDATION, + DATASOURCE_FAILURE, + MANAGER_LOCKFILE_ERROR, + MANAGER_NO_PACKAGE_FILES, + PLATFORM_AUTHENTICATION_ERROR, + PLATFORM_BAD_CREDENTIALS, + PLATFORM_FAILURE, + PLATFORM_INTEGRATION_UNAUTHORIZED, + PLATFORM_RATE_LIMIT_EXCEEDED, + REPOSITORY_ACCESS_FORBIDDEN, + REPOSITORY_ARCHIVED, + REPOSITORY_BLOCKED, + REPOSITORY_CANNOT_FORK, + REPOSITORY_CHANGED, + REPOSITORY_DISABLED, + REPOSITORY_EMPTY, + REPOSITORY_FORKED, + REPOSITORY_MIRRORED, + REPOSITORY_NO_VULNERABILITY, + REPOSITORY_NOT_FOUND, + REPOSITORY_RENAMED, + REPOSITORY_TEMPORARY_ERROR, + REPOSITORY_UNINITIATED, + SYSTEM_INSUFFICIENT_DISK_SPACE, + UNKNOWN_ERROR, +} from '../../../lib/constants/error-messages'; import { RenovateConfig, getConfig } from '../../util'; jest.mock('../../../lib/workers/repository/error-config'); @@ -12,30 +39,30 @@ beforeEach(() => { describe('workers/repository/error', () => { describe('handleError()', () => { const errors = [ - 'uninitiated', - 'empty', - 'disabled', - 'repository-changed', - 'fork', - 'no-package-files', - 'config-validation', - 'registry-failure', - 'archived', - 'mirror', - 'renamed', - 'blocked', - 'not-found', - 'forbidden', - 'bad-credentials', - 'rate-limit-exceeded', - 'lockfile-error', - 'disk-space', - 'platform-failure', - 'no-vulnerability-alerts', - 'cannot-fork', - 'integration-unauthorized', - 'authentication-error', - 'temporary-error', + REPOSITORY_UNINITIATED, + REPOSITORY_EMPTY, + REPOSITORY_DISABLED, + REPOSITORY_CHANGED, + REPOSITORY_FORKED, + MANAGER_NO_PACKAGE_FILES, + CONFIG_VALIDATION, + DATASOURCE_FAILURE, + REPOSITORY_ARCHIVED, + REPOSITORY_MIRRORED, + REPOSITORY_RENAMED, + REPOSITORY_BLOCKED, + REPOSITORY_NOT_FOUND, + REPOSITORY_ACCESS_FORBIDDEN, + PLATFORM_BAD_CREDENTIALS, + PLATFORM_RATE_LIMIT_EXCEEDED, + MANAGER_LOCKFILE_ERROR, + SYSTEM_INSUFFICIENT_DISK_SPACE, + PLATFORM_FAILURE, + REPOSITORY_NO_VULNERABILITY, + REPOSITORY_CANNOT_FORK, + PLATFORM_INTEGRATION_UNAUTHORIZED, + PLATFORM_AUTHENTICATION_ERROR, + REPOSITORY_TEMPORARY_ERROR, ]; errors.forEach(err => { it(`errors ${err}`, async () => { @@ -48,18 +75,18 @@ describe('workers/repository/error', () => { "fatal: unable to access 'https://**redacted**@gitlab.com/learnox/learnox.git/': The requested URL returned error: 500\n" ); const res = await handleError(config, gitError); - expect(res).toEqual('platform-failure'); + expect(res).toEqual(PLATFORM_FAILURE); }); it('rewrites git remote error', async () => { const gitError = new Error( 'fatal: remote error: access denied or repository not exported: /b/nw/bd/27/47/159945428/108610112.git\n' ); const res = await handleError(config, gitError); - expect(res).toEqual('platform-failure'); + expect(res).toEqual(PLATFORM_FAILURE); }); it('handles unknown error', async () => { const res = await handleError(config, new Error('abcdefg')); - expect(res).toEqual('unknown-error'); + expect(res).toEqual(UNKNOWN_ERROR); }); }); }); diff --git a/test/workers/repository/init/vulnerability.spec.ts b/test/workers/repository/init/vulnerability.spec.ts index 715af5e5e032050306536744988219fb439a3342..adcf089f4b302a0b72dcd36a6a7b398ae86632f2 100644 --- a/test/workers/repository/init/vulnerability.spec.ts +++ b/test/workers/repository/init/vulnerability.spec.ts @@ -1,5 +1,6 @@ import { detectVulnerabilityAlerts } from '../../../../lib/workers/repository/init/vulnerability'; import { platform, defaultConfig, RenovateConfig } from '../../../util'; +import { REPOSITORY_NO_VULNERABILITY } from '../../../../lib/constants/error-messages'; let config: RenovateConfig; beforeEach(() => { @@ -26,7 +27,7 @@ describe('workers/repository/init/vulnerability', () => { config.vulnerabilityAlertsOnly = true; platform.getVulnerabilityAlerts.mockResolvedValue([]); await expect(detectVulnerabilityAlerts(config)).rejects.toThrow( - /no-vulnerability-alerts/ + REPOSITORY_NO_VULNERABILITY ); }); it('returns alerts', async () => { diff --git a/test/workers/repository/process/lookup/index.spec.ts b/test/workers/repository/process/lookup/index.spec.ts index 8b02b70b89dcc49b42e7059f2533c7b30bc9699a..fa9b276892ed7d447b6bf161ea4ebb1e6256220a 100644 --- a/test/workers/repository/process/lookup/index.spec.ts +++ b/test/workers/repository/process/lookup/index.spec.ts @@ -10,6 +10,7 @@ import typescriptJson from '../../../../config/npm/_fixtures/typescript.json'; import * as _docker from '../../../../../lib/datasource/docker'; import * as _gitSubmodules from '../../../../../lib/datasource/git-submodules'; import { mocked, getConfig } from '../../../../util'; +import { CONFIG_VALIDATION } from '../../../../../lib/constants/error-messages'; jest.mock('../../../../../lib/datasource/docker'); jest.mock('../../../../../lib/datasource/git-submodules'); @@ -179,7 +180,7 @@ describe('workers/repository/process/lookup', () => { .get('/q') .reply(200, qJson); await expect(lookup.lookupUpdates(config)).rejects.toThrow( - Error('config-validation') + Error(CONFIG_VALIDATION) ); }); it('returns minor update if separate patches not configured', async () => {