mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-12 06:56:24 +00:00
refactor: ExternalHostError (#6563)
This commit is contained in:
parent
cb84fa9d9b
commit
52a074e041
51 changed files with 211 additions and 223 deletions
|
@ -1,6 +1,6 @@
|
||||||
import { PLATFORM_FAILURE } from '../../../constants/error-messages';
|
|
||||||
import { PLATFORM_TYPE_GITHUB } from '../../../constants/platforms';
|
import { PLATFORM_TYPE_GITHUB } from '../../../constants/platforms';
|
||||||
import { logger } from '../../../logger';
|
import { logger } from '../../../logger';
|
||||||
|
import { ExternalHostError } from '../../../types/error';
|
||||||
import { Http, HttpOptions } from '../../../util/http';
|
import { Http, HttpOptions } from '../../../util/http';
|
||||||
import { Preset, PresetConfig } from '../common';
|
import { Preset, PresetConfig } from '../common';
|
||||||
import { PRESET_DEP_NOT_FOUND, fetchPreset } from '../util';
|
import { PRESET_DEP_NOT_FOUND, fetchPreset } from '../util';
|
||||||
|
@ -27,7 +27,7 @@ export async function fetchJSONFile(
|
||||||
res = await http.getJson(url, opts);
|
res = await http.getJson(url, opts);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// istanbul ignore if: not testable with nock
|
// istanbul ignore if: not testable with nock
|
||||||
if (err.message === PLATFORM_FAILURE) {
|
if (err instanceof ExternalHostError) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
logger.debug(
|
logger.debug(
|
||||||
|
|
|
@ -70,7 +70,7 @@ Array [
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`config/presets/gitlab/index getPreset() throws platform-failure 1`] = `
|
exports[`config/presets/gitlab/index getPreset() throws EXTERNAL_HOST_ERROR 1`] = `
|
||||||
Array [
|
Array [
|
||||||
Object {
|
Object {
|
||||||
"headers": Object {
|
"headers": Object {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as httpMock from '../../../../test/httpMock';
|
import * as httpMock from '../../../../test/httpMock';
|
||||||
import { getName } from '../../../../test/util';
|
import { getName } from '../../../../test/util';
|
||||||
import { PLATFORM_FAILURE } from '../../../constants/error-messages';
|
import { EXTERNAL_HOST_ERROR } from '../../../constants/error-messages';
|
||||||
import { PRESET_DEP_NOT_FOUND } from '../util';
|
import { PRESET_DEP_NOT_FOUND } from '../util';
|
||||||
import * as gitlab from '.';
|
import * as gitlab from '.';
|
||||||
|
|
||||||
|
@ -18,14 +18,14 @@ describe(getName(__filename), () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getPreset()', () => {
|
describe('getPreset()', () => {
|
||||||
it('throws platform-failure', async () => {
|
it('throws EXTERNAL_HOST_ERROR', async () => {
|
||||||
httpMock.scope(gitlabApiHost).get(`${basePath}/branches`).reply(500);
|
httpMock.scope(gitlabApiHost).get(`${basePath}/branches`).reply(500);
|
||||||
await expect(
|
await expect(
|
||||||
gitlab.getPreset({
|
gitlab.getPreset({
|
||||||
packageName: 'some/repo',
|
packageName: 'some/repo',
|
||||||
presetName: 'non-default',
|
presetName: 'non-default',
|
||||||
})
|
})
|
||||||
).rejects.toThrow(PLATFORM_FAILURE);
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
expect(httpMock.getTrace()).toMatchSnapshot();
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { PLATFORM_FAILURE } from '../../../constants/error-messages';
|
|
||||||
import { logger } from '../../../logger';
|
import { logger } from '../../../logger';
|
||||||
|
import { ExternalHostError } from '../../../types/error';
|
||||||
import type { GitLabBranch } from '../../../types/platform/gitlab';
|
import type { GitLabBranch } from '../../../types/platform/gitlab';
|
||||||
import { GitlabHttp } from '../../../util/http/gitlab';
|
import { GitlabHttp } from '../../../util/http/gitlab';
|
||||||
import { Preset, PresetConfig } from '../common';
|
import { Preset, PresetConfig } from '../common';
|
||||||
|
@ -42,7 +42,7 @@ export async function fetchJSONFile(
|
||||||
const url = `${endpoint}projects/${urlEncodedRepo}/repository/files/${urlEncodedPkgName}/raw?ref=${defautlBranchName}`;
|
const url = `${endpoint}projects/${urlEncodedRepo}/repository/files/${urlEncodedPkgName}/raw?ref=${defautlBranchName}`;
|
||||||
return (await gitlabApi.getJson<Preset>(url)).body;
|
return (await gitlabApi.getJson<Preset>(url)).body;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.message === PLATFORM_FAILURE) {
|
if (err instanceof ExternalHostError) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
logger.debug(
|
logger.debug(
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
import is from '@sindresorhus/is';
|
import is from '@sindresorhus/is';
|
||||||
import {
|
import { CONFIG_VALIDATION } from '../../constants/error-messages';
|
||||||
CONFIG_VALIDATION,
|
|
||||||
DATASOURCE_FAILURE,
|
|
||||||
PLATFORM_FAILURE,
|
|
||||||
} from '../../constants/error-messages';
|
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import { regEx } from '../../util/regex';
|
import { regEx } from '../../util/regex';
|
||||||
import { RenovateConfig } from '../common';
|
import { RenovateConfig } from '../common';
|
||||||
import * as massage from '../massage';
|
import * as massage from '../massage';
|
||||||
|
@ -207,10 +204,7 @@ export async function resolveConfigPresets(
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.debug({ preset, err }, 'Preset fetch error');
|
logger.debug({ preset, err }, 'Preset fetch error');
|
||||||
// istanbul ignore if
|
// istanbul ignore if
|
||||||
if (
|
if (err instanceof ExternalHostError) {
|
||||||
err.message === PLATFORM_FAILURE ||
|
|
||||||
err.message === DATASOURCE_FAILURE
|
|
||||||
) {
|
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
const error = new Error(CONFIG_VALIDATION);
|
const error = new Error(CONFIG_VALIDATION);
|
||||||
|
|
|
@ -5,7 +5,6 @@ export const SYSTEM_INSUFFICIENT_MEMORY = 'out-of-memory';
|
||||||
// Platform Error
|
// Platform Error
|
||||||
export const PLATFORM_AUTHENTICATION_ERROR = 'authentication-error';
|
export const PLATFORM_AUTHENTICATION_ERROR = 'authentication-error';
|
||||||
export const PLATFORM_BAD_CREDENTIALS = 'bad-credentials';
|
export const PLATFORM_BAD_CREDENTIALS = 'bad-credentials';
|
||||||
export const PLATFORM_FAILURE = 'platform-failure';
|
|
||||||
export const PLATFORM_GPG_FAILED = 'gpg-failed';
|
export const PLATFORM_GPG_FAILED = 'gpg-failed';
|
||||||
export const PLATFORM_INTEGRATION_UNAUTHORIZED = 'integration-unauthorized';
|
export const PLATFORM_INTEGRATION_UNAUTHORIZED = 'integration-unauthorized';
|
||||||
export const PLATFORM_NOT_FOUND = 'platform-not-found';
|
export const PLATFORM_NOT_FOUND = 'platform-not-found';
|
||||||
|
@ -34,8 +33,8 @@ export const REPOSITORY_UNINITIATED = 'uninitiated';
|
||||||
export const MANAGER_LOCKFILE_ERROR = 'lockfile-error';
|
export const MANAGER_LOCKFILE_ERROR = 'lockfile-error';
|
||||||
export const MANAGER_NO_PACKAGE_FILES = 'no-package-files';
|
export const MANAGER_NO_PACKAGE_FILES = 'no-package-files';
|
||||||
|
|
||||||
// Datasource error
|
// Host error
|
||||||
export const DATASOURCE_FAILURE = 'registry-failure';
|
export const EXTERNAL_HOST_ERROR = 'external-host-error';
|
||||||
|
|
||||||
// Worker Error
|
// Worker Error
|
||||||
export const WORKER_FILE_UPDATE_FAILED = 'update-failure';
|
export const WORKER_FILE_UPDATE_FAILED = 'update-failure';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { getPkgReleases } from '..';
|
import { getPkgReleases } from '..';
|
||||||
import * as httpMock from '../../../test/httpMock';
|
import * as httpMock from '../../../test/httpMock';
|
||||||
import { DATASOURCE_FAILURE } from '../../constants/error-messages';
|
import { EXTERNAL_HOST_ERROR } from '../../constants/error-messages';
|
||||||
import { id as datasource } from '.';
|
import { id as datasource } from '.';
|
||||||
|
|
||||||
let res1 = fs.readFileSync(
|
let res1 = fs.readFileSync(
|
||||||
|
@ -36,14 +36,14 @@ describe('datasource/cdnjs', () => {
|
||||||
httpMock.scope(baseUrl).get(pathFor('foo/bar')).reply(200, null);
|
httpMock.scope(baseUrl).get(pathFor('foo/bar')).reply(200, null);
|
||||||
await expect(
|
await expect(
|
||||||
getPkgReleases({ datasource, depName: 'foo/bar' })
|
getPkgReleases({ datasource, depName: 'foo/bar' })
|
||||||
).rejects.toThrow(DATASOURCE_FAILURE);
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
expect(httpMock.getTrace()).toMatchSnapshot();
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
it('throws for error', async () => {
|
it('throws for error', async () => {
|
||||||
httpMock.scope(baseUrl).get(pathFor('foo/bar')).replyWithError('error');
|
httpMock.scope(baseUrl).get(pathFor('foo/bar')).replyWithError('error');
|
||||||
await expect(
|
await expect(
|
||||||
getPkgReleases({ datasource, depName: 'foo/bar' })
|
getPkgReleases({ datasource, depName: 'foo/bar' })
|
||||||
).rejects.toThrow(DATASOURCE_FAILURE);
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
expect(httpMock.getTrace()).toMatchSnapshot();
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
it('returns null for 404', async () => {
|
it('returns null for 404', async () => {
|
||||||
|
@ -70,28 +70,28 @@ describe('datasource/cdnjs', () => {
|
||||||
httpMock.scope(baseUrl).get(pathFor('foo/bar')).reply(401);
|
httpMock.scope(baseUrl).get(pathFor('foo/bar')).reply(401);
|
||||||
await expect(
|
await expect(
|
||||||
getPkgReleases({ datasource, depName: 'foo/bar' })
|
getPkgReleases({ datasource, depName: 'foo/bar' })
|
||||||
).rejects.toThrow(DATASOURCE_FAILURE);
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
expect(httpMock.getTrace()).toMatchSnapshot();
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
it('throws for 429', async () => {
|
it('throws for 429', async () => {
|
||||||
httpMock.scope(baseUrl).get(pathFor('foo/bar')).reply(429);
|
httpMock.scope(baseUrl).get(pathFor('foo/bar')).reply(429);
|
||||||
await expect(
|
await expect(
|
||||||
getPkgReleases({ datasource, depName: 'foo/bar' })
|
getPkgReleases({ datasource, depName: 'foo/bar' })
|
||||||
).rejects.toThrow(DATASOURCE_FAILURE);
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
expect(httpMock.getTrace()).toMatchSnapshot();
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
it('throws for 5xx', async () => {
|
it('throws for 5xx', async () => {
|
||||||
httpMock.scope(baseUrl).get(pathFor('foo/bar')).reply(502);
|
httpMock.scope(baseUrl).get(pathFor('foo/bar')).reply(502);
|
||||||
await expect(
|
await expect(
|
||||||
getPkgReleases({ datasource, depName: 'foo/bar' })
|
getPkgReleases({ datasource, depName: 'foo/bar' })
|
||||||
).rejects.toThrow(DATASOURCE_FAILURE);
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
expect(httpMock.getTrace()).toMatchSnapshot();
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
it('returns null for unknown error', async () => {
|
it('returns null for unknown error', async () => {
|
||||||
httpMock.scope(baseUrl).get(pathFor('foo/bar')).replyWithError('error');
|
httpMock.scope(baseUrl).get(pathFor('foo/bar')).replyWithError('error');
|
||||||
await expect(
|
await expect(
|
||||||
getPkgReleases({ datasource, depName: 'foo/bar' })
|
getPkgReleases({ datasource, depName: 'foo/bar' })
|
||||||
).rejects.toThrow(DATASOURCE_FAILURE);
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
expect(httpMock.getTrace()).toMatchSnapshot();
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
it('processes real data', async () => {
|
it('processes real data', async () => {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import { Http } from '../../util/http';
|
import { Http } from '../../util/http';
|
||||||
import { CachePromise, cacheAble } from '../cache';
|
import { CachePromise, cacheAble } from '../cache';
|
||||||
import { DatasourceError, GetReleasesConfig, ReleaseResult } from '../common';
|
import { GetReleasesConfig, ReleaseResult } from '../common';
|
||||||
|
|
||||||
export const id = 'cdnjs';
|
export const id = 'cdnjs';
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ export async function getReleases({
|
||||||
logger.debug({ library }, 'cdnjs library not found');
|
logger.debug({ library }, 'cdnjs library not found');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// Throw a DatasourceError for all other types of errors
|
// Throw an ExternalHostError for all other types of errors
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import { DATASOURCE_FAILURE } from '../constants/error-messages';
|
|
||||||
|
|
||||||
export interface Config {
|
export interface Config {
|
||||||
datasource?: string;
|
datasource?: string;
|
||||||
depName?: string;
|
depName?: string;
|
||||||
|
@ -80,18 +78,3 @@ export interface Datasource {
|
||||||
defaultConfig?: object;
|
defaultConfig?: object;
|
||||||
registryStrategy?: 'first' | 'hunt' | 'merge';
|
registryStrategy?: 'first' | 'hunt' | 'merge';
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DatasourceError extends Error {
|
|
||||||
err: Error;
|
|
||||||
|
|
||||||
datasource?: string;
|
|
||||||
|
|
||||||
lookupName?: string;
|
|
||||||
|
|
||||||
constructor(err: Error) {
|
|
||||||
super(DATASOURCE_FAILURE);
|
|
||||||
// Set the prototype explicitly: https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
|
||||||
Object.setPrototypeOf(this, DatasourceError.prototype);
|
|
||||||
this.err = err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -764,7 +764,7 @@ Array [
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`datasource/crate getReleases throws for 5xx 1`] = `[Error: registry-failure]`;
|
exports[`datasource/crate getReleases throws for 5xx 1`] = `[Error: external-host-error]`;
|
||||||
|
|
||||||
exports[`datasource/crate getReleases throws for 5xx 2`] = `
|
exports[`datasource/crate getReleases throws for 5xx 2`] = `
|
||||||
Array [
|
Array [
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import * as globalCache from '../../util/cache/global';
|
import * as globalCache from '../../util/cache/global';
|
||||||
import { Http } from '../../util/http';
|
import { Http } from '../../util/http';
|
||||||
import {
|
import { GetReleasesConfig, Release, ReleaseResult } from '../common';
|
||||||
DatasourceError,
|
|
||||||
GetReleasesConfig,
|
|
||||||
Release,
|
|
||||||
ReleaseResult,
|
|
||||||
} from '../common';
|
|
||||||
|
|
||||||
export const id = 'crate';
|
export const id = 'crate';
|
||||||
|
|
||||||
|
@ -105,7 +101,7 @@ export async function getReleases({
|
||||||
err.statusCode === 429 ||
|
err.statusCode === 429 ||
|
||||||
(err.statusCode >= 500 && err.statusCode < 600)
|
(err.statusCode >= 500 && err.statusCode < 600)
|
||||||
) {
|
) {
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
logger.warn({ err, lookupName }, 'crates.io lookup failure: Unknown error');
|
logger.warn({ err, lookupName }, 'crates.io lookup failure: Unknown error');
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -144,7 +144,7 @@ Array [
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`datasource/dart getReleases throws for 5xx 1`] = `[Error: registry-failure]`;
|
exports[`datasource/dart getReleases throws for 5xx 1`] = `[Error: external-host-error]`;
|
||||||
|
|
||||||
exports[`datasource/dart getReleases throws for 5xx 2`] = `
|
exports[`datasource/dart getReleases throws for 5xx 2`] = `
|
||||||
Array [
|
Array [
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import { Http, HttpResponse } from '../../util/http';
|
import { Http, HttpResponse } from '../../util/http';
|
||||||
import { DatasourceError, GetReleasesConfig, ReleaseResult } from '../common';
|
import { GetReleasesConfig, ReleaseResult } from '../common';
|
||||||
|
|
||||||
export const id = 'dart';
|
export const id = 'dart';
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ export async function getReleases({
|
||||||
err.statusCode === 429 ||
|
err.statusCode === 429 ||
|
||||||
(err.statusCode >= 500 && err.statusCode < 600)
|
(err.statusCode >= 500 && err.statusCode < 600)
|
||||||
) {
|
) {
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
logger.warn(
|
logger.warn(
|
||||||
{ err, lookupName },
|
{ err, lookupName },
|
||||||
|
|
|
@ -2,7 +2,7 @@ import AWS from 'aws-sdk';
|
||||||
import AWSMock from 'aws-sdk-mock';
|
import AWSMock from 'aws-sdk-mock';
|
||||||
import { getDigest, getPkgReleases } from '..';
|
import { getDigest, getPkgReleases } from '..';
|
||||||
import * as httpMock from '../../../test/httpMock';
|
import * as httpMock from '../../../test/httpMock';
|
||||||
import { DATASOURCE_FAILURE } from '../../constants/error-messages';
|
import { EXTERNAL_HOST_ERROR } from '../../constants/error-messages';
|
||||||
import * as _hostRules from '../../util/host-rules';
|
import * as _hostRules from '../../util/host-rules';
|
||||||
import * as docker from '.';
|
import * as docker from '.';
|
||||||
|
|
||||||
|
@ -331,13 +331,13 @@ describe('api/docker', () => {
|
||||||
httpMock.scope(baseUrl).get('/').replyWithError({ statusCode: 429 });
|
httpMock.scope(baseUrl).get('/').replyWithError({ statusCode: 429 });
|
||||||
await expect(
|
await expect(
|
||||||
getDigest({ datasource: 'docker', depName: 'some-dep' }, 'latest')
|
getDigest({ datasource: 'docker', depName: 'some-dep' }, 'latest')
|
||||||
).rejects.toThrow(Error(DATASOURCE_FAILURE));
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
});
|
});
|
||||||
it('should throw error for 5xx', async () => {
|
it('should throw error for 5xx', async () => {
|
||||||
httpMock.scope(baseUrl).get('/').replyWithError({ statusCode: 504 });
|
httpMock.scope(baseUrl).get('/').replyWithError({ statusCode: 504 });
|
||||||
await expect(
|
await expect(
|
||||||
getDigest({ datasource: 'docker', depName: 'some-dep' }, 'latest')
|
getDigest({ datasource: 'docker', depName: 'some-dep' }, 'latest')
|
||||||
).rejects.toThrow(Error(DATASOURCE_FAILURE));
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('getReleases', () => {
|
describe('getReleases', () => {
|
||||||
|
|
|
@ -6,10 +6,11 @@ import parseLinkHeader from 'parse-link-header';
|
||||||
import wwwAuthenticate from 'www-authenticate';
|
import wwwAuthenticate from 'www-authenticate';
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
import { HostRule } from '../../types';
|
import { HostRule } from '../../types';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import * as globalCache from '../../util/cache/global';
|
import * as globalCache from '../../util/cache/global';
|
||||||
import * as hostRules from '../../util/host-rules';
|
import * as hostRules from '../../util/host-rules';
|
||||||
import { Http, HttpResponse } from '../../util/http';
|
import { Http, HttpResponse } from '../../util/http';
|
||||||
import { DatasourceError, GetReleasesConfig, ReleaseResult } from '../common';
|
import { GetReleasesConfig, ReleaseResult } from '../common';
|
||||||
|
|
||||||
// TODO: add got typings when available
|
// TODO: add got typings when available
|
||||||
// TODO: replace www-authenticate with https://www.npmjs.com/package/auth-header ?
|
// TODO: replace www-authenticate with https://www.npmjs.com/package/auth-header ?
|
||||||
|
@ -220,14 +221,14 @@ async function getAuthHeaders(
|
||||||
}
|
}
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
if (err.name === 'RequestError' && registry.endsWith('docker.io')) { // lgtm [js/incomplete-url-substring-sanitization]
|
if (err.name === 'RequestError' && registry.endsWith('docker.io')) { // lgtm [js/incomplete-url-substring-sanitization]
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
if (err.statusCode === 429 && registry.endsWith('docker.io')) { // lgtm [js/incomplete-url-substring-sanitization]
|
if (err.statusCode === 429 && registry.endsWith('docker.io')) { // lgtm [js/incomplete-url-substring-sanitization]
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
if (err.statusCode >= 500 && err.statusCode < 600) {
|
if (err.statusCode >= 500 && err.statusCode < 600) {
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
logger.warn(
|
logger.warn(
|
||||||
{ registry, dockerRepository: repository, err },
|
{ registry, dockerRepository: repository, err },
|
||||||
|
@ -267,7 +268,7 @@ async function getManifestResponse(
|
||||||
});
|
});
|
||||||
return manifestResponse;
|
return manifestResponse;
|
||||||
} catch (err) /* istanbul ignore next */ {
|
} catch (err) /* istanbul ignore next */ {
|
||||||
if (err instanceof DatasourceError) {
|
if (err instanceof ExternalHostError) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
if (err.statusCode === 401) {
|
if (err.statusCode === 401) {
|
||||||
|
@ -292,10 +293,10 @@ async function getManifestResponse(
|
||||||
}
|
}
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
if (err.statusCode === 429 && registry.endsWith('docker.io')) { // lgtm [js/incomplete-url-substring-sanitization]
|
if (err.statusCode === 429 && registry.endsWith('docker.io')) { // lgtm [js/incomplete-url-substring-sanitization]
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
if (err.statusCode >= 500 && err.statusCode < 600) {
|
if (err.statusCode >= 500 && err.statusCode < 600) {
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
if (err.code === 'ETIMEDOUT') {
|
if (err.code === 'ETIMEDOUT') {
|
||||||
logger.debug(
|
logger.debug(
|
||||||
|
@ -356,7 +357,7 @@ export async function getDigest(
|
||||||
logger.debug({ digest }, 'Got docker digest');
|
logger.debug({ digest }, 'Got docker digest');
|
||||||
}
|
}
|
||||||
} catch (err) /* istanbul ignore next */ {
|
} catch (err) /* istanbul ignore next */ {
|
||||||
if (err instanceof DatasourceError) {
|
if (err instanceof ExternalHostError) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
logger.debug(
|
logger.debug(
|
||||||
|
@ -413,7 +414,7 @@ async function getTags(
|
||||||
await globalCache.set(cacheNamespace, cacheKey, tags, cacheMinutes);
|
await globalCache.set(cacheNamespace, cacheKey, tags, cacheMinutes);
|
||||||
return tags;
|
return tags;
|
||||||
} catch (err) /* istanbul ignore next */ {
|
} catch (err) /* istanbul ignore next */ {
|
||||||
if (err instanceof DatasourceError) {
|
if (err instanceof ExternalHostError) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
logger.debug(
|
logger.debug(
|
||||||
|
@ -441,14 +442,14 @@ async function getTags(
|
||||||
{ registry, dockerRepository: repository, err },
|
{ registry, dockerRepository: repository, err },
|
||||||
'docker registry failure: too many requests'
|
'docker registry failure: too many requests'
|
||||||
);
|
);
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
if (err.statusCode >= 500 && err.statusCode < 600) {
|
if (err.statusCode >= 500 && err.statusCode < 600) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
{ registry, dockerRepository: repository, err },
|
{ registry, dockerRepository: repository, err },
|
||||||
'docker registry failure: internal error'
|
'docker registry failure: internal error'
|
||||||
);
|
);
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
if (err.code === 'ETIMEDOUT') {
|
if (err.code === 'ETIMEDOUT') {
|
||||||
logger.debug(
|
logger.debug(
|
||||||
|
@ -543,7 +544,7 @@ async function getLabels(
|
||||||
await globalCache.set(cacheNamespace, cacheKey, labels, cacheMinutes);
|
await globalCache.set(cacheNamespace, cacheKey, labels, cacheMinutes);
|
||||||
return labels;
|
return labels;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof DatasourceError) {
|
if (err instanceof ExternalHostError) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
if (err.statusCode === 400 || err.statusCode === 401) {
|
if (err.statusCode === 400 || err.statusCode === 401) {
|
||||||
|
|
|
@ -119,7 +119,7 @@ Array [
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`datasource/galaxy getReleases throws for 5xx 1`] = `[Error: registry-failure]`;
|
exports[`datasource/galaxy getReleases throws for 5xx 1`] = `[Error: external-host-error]`;
|
||||||
|
|
||||||
exports[`datasource/galaxy getReleases throws for 5xx 2`] = `
|
exports[`datasource/galaxy getReleases throws for 5xx 2`] = `
|
||||||
Array [
|
Array [
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import * as globalCache from '../../util/cache/global';
|
import * as globalCache from '../../util/cache/global';
|
||||||
import { Http } from '../../util/http';
|
import { Http } from '../../util/http';
|
||||||
import {
|
import { GetReleasesConfig, Release, ReleaseResult } from '../common';
|
||||||
DatasourceError,
|
|
||||||
GetReleasesConfig,
|
|
||||||
Release,
|
|
||||||
ReleaseResult,
|
|
||||||
} from '../common';
|
|
||||||
|
|
||||||
export const id = 'galaxy';
|
export const id = 'galaxy';
|
||||||
|
|
||||||
|
@ -101,7 +97,7 @@ export async function getReleases({
|
||||||
err.statusCode === 429 ||
|
err.statusCode === 429 ||
|
||||||
(err.statusCode >= 500 && err.statusCode < 600)
|
(err.statusCode >= 500 && err.statusCode < 600)
|
||||||
) {
|
) {
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import { Http } from '../../util/http';
|
import { Http } from '../../util/http';
|
||||||
import { regEx } from '../../util/regex';
|
import { regEx } from '../../util/regex';
|
||||||
import { DatasourceError, GetReleasesConfig, ReleaseResult } from '../common';
|
import { GetReleasesConfig, ReleaseResult } from '../common';
|
||||||
|
|
||||||
export const id = 'gradle-version';
|
export const id = 'gradle-version';
|
||||||
export const defaultRegistryUrls = ['https://services.gradle.org/versions/all'];
|
export const defaultRegistryUrls = ['https://services.gradle.org/versions/all'];
|
||||||
|
@ -50,7 +51,7 @@ export async function getReleases({
|
||||||
}));
|
}));
|
||||||
} catch (err) /* istanbul ignore next */ {
|
} catch (err) /* istanbul ignore next */ {
|
||||||
if (err.host === 'services.gradle.org') {
|
if (err.host === 'services.gradle.org') {
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
logger.debug({ err }, 'gradle-version err');
|
logger.debug({ err }, 'gradle-version err');
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -244,7 +244,7 @@ Array [
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`datasource/helm getReleases throws for 5xx 1`] = `[Error: registry-failure]`;
|
exports[`datasource/helm getReleases throws for 5xx 1`] = `[Error: external-host-error]`;
|
||||||
|
|
||||||
exports[`datasource/helm getReleases throws for 5xx 2`] = `
|
exports[`datasource/helm getReleases throws for 5xx 2`] = `
|
||||||
Array [
|
Array [
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
|
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import * as globalCache from '../../util/cache/global';
|
import * as globalCache from '../../util/cache/global';
|
||||||
import { Http } from '../../util/http';
|
import { Http } from '../../util/http';
|
||||||
import { ensureTrailingSlash } from '../../util/url';
|
import { ensureTrailingSlash } from '../../util/url';
|
||||||
import { DatasourceError, GetReleasesConfig, ReleaseResult } from '../common';
|
import { GetReleasesConfig, ReleaseResult } from '../common';
|
||||||
|
|
||||||
export const id = 'helm';
|
export const id = 'helm';
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ export async function getRepositoryData(
|
||||||
err.statusCode === 429 ||
|
err.statusCode === 429 ||
|
||||||
(err.statusCode >= 500 && err.statusCode < 600)
|
(err.statusCode >= 500 && err.statusCode < 600)
|
||||||
) {
|
) {
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
// istanbul ignore if
|
// istanbul ignore if
|
||||||
if (err.name === 'UnsupportedProtocolError') {
|
if (err.name === 'UnsupportedProtocolError') {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { getPkgReleases } from '..';
|
import { getPkgReleases } from '..';
|
||||||
import * as httpMock from '../../../test/httpMock';
|
import * as httpMock from '../../../test/httpMock';
|
||||||
import { DATASOURCE_FAILURE } from '../../constants/error-messages';
|
import { EXTERNAL_HOST_ERROR } from '../../constants/error-messages';
|
||||||
import * as _hostRules from '../../util/host-rules';
|
import * as _hostRules from '../../util/host-rules';
|
||||||
import { id as datasource } from '.';
|
import { id as datasource } from '.';
|
||||||
|
|
||||||
|
@ -67,14 +67,14 @@ describe('datasource/hex', () => {
|
||||||
httpMock.scope(baseUrl).get('/some_crate').reply(429);
|
httpMock.scope(baseUrl).get('/some_crate').reply(429);
|
||||||
await expect(
|
await expect(
|
||||||
getPkgReleases({ datasource, depName: 'some_crate' })
|
getPkgReleases({ datasource, depName: 'some_crate' })
|
||||||
).rejects.toThrow(DATASOURCE_FAILURE);
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
expect(httpMock.getTrace()).toMatchSnapshot();
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
it('throws for 5xx', async () => {
|
it('throws for 5xx', async () => {
|
||||||
httpMock.scope(baseUrl).get('/some_crate').reply(502);
|
httpMock.scope(baseUrl).get('/some_crate').reply(502);
|
||||||
await expect(
|
await expect(
|
||||||
getPkgReleases({ datasource, depName: 'some_crate' })
|
getPkgReleases({ datasource, depName: 'some_crate' })
|
||||||
).rejects.toThrow(DATASOURCE_FAILURE);
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
expect(httpMock.getTrace()).toMatchSnapshot();
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
it('returns null for unknown error', async () => {
|
it('returns null for unknown error', async () => {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import { Http } from '../../util/http';
|
import { Http } from '../../util/http';
|
||||||
import { DatasourceError, GetReleasesConfig, ReleaseResult } from '../common';
|
import { GetReleasesConfig, ReleaseResult } from '../common';
|
||||||
|
|
||||||
export const id = 'hex';
|
export const id = 'hex';
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ export async function getReleases({
|
||||||
err.statusCode === 429 ||
|
err.statusCode === 429 ||
|
||||||
(err.statusCode >= 500 && err.statusCode < 600)
|
(err.statusCode >= 500 && err.statusCode < 600)
|
||||||
) {
|
) {
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err.statusCode === 401) {
|
if (err.statusCode === 401) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { mocked } from '../../test/util';
|
import { mocked } from '../../test/util';
|
||||||
import { DATASOURCE_FAILURE } from '../constants/error-messages';
|
import { EXTERNAL_HOST_ERROR } from '../constants/error-messages';
|
||||||
|
import { ExternalHostError } from '../types/error';
|
||||||
import { loadModules } from '../util/modules';
|
import { loadModules } from '../util/modules';
|
||||||
import { DatasourceError } from './common';
|
|
||||||
import * as datasourceDocker from './docker';
|
import * as datasourceDocker from './docker';
|
||||||
import * as datasourceGithubTags from './github-tags';
|
import * as datasourceGithubTags from './github-tags';
|
||||||
import * as datasourceMaven from './maven';
|
import * as datasourceMaven from './maven';
|
||||||
|
@ -131,9 +131,9 @@ describe('datasource/index', () => {
|
||||||
});
|
});
|
||||||
expect(res).not.toBeNull();
|
expect(res).not.toBeNull();
|
||||||
});
|
});
|
||||||
it('hunts registries and aborts on DatasourceError', async () => {
|
it('hunts registries and aborts on ExternalHostError', async () => {
|
||||||
packagistDatasource.getReleases.mockImplementationOnce(() => {
|
packagistDatasource.getReleases.mockImplementationOnce(() => {
|
||||||
throw new DatasourceError(new Error());
|
throw new ExternalHostError(new Error());
|
||||||
});
|
});
|
||||||
await expect(
|
await expect(
|
||||||
datasource.getPkgReleases({
|
datasource.getPkgReleases({
|
||||||
|
@ -141,7 +141,7 @@ describe('datasource/index', () => {
|
||||||
depName: 'something',
|
depName: 'something',
|
||||||
registryUrls: ['https://reg1.com', 'https://reg2.io'],
|
registryUrls: ['https://reg1.com', 'https://reg2.io'],
|
||||||
})
|
})
|
||||||
).rejects.toThrow(DATASOURCE_FAILURE);
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
});
|
});
|
||||||
it('hunts registries and passes on error', async () => {
|
it('hunts registries and passes on error', async () => {
|
||||||
packagistDatasource.getReleases.mockImplementationOnce(() => {
|
packagistDatasource.getReleases.mockImplementationOnce(() => {
|
||||||
|
@ -173,9 +173,9 @@ describe('datasource/index', () => {
|
||||||
expect(res).toMatchSnapshot();
|
expect(res).toMatchSnapshot();
|
||||||
expect(res.releases).toHaveLength(2);
|
expect(res.releases).toHaveLength(2);
|
||||||
});
|
});
|
||||||
it('merges registries and aborts on DatasourceError', async () => {
|
it('merges registries and aborts on ExternalHostError', async () => {
|
||||||
mavenDatasource.getReleases.mockImplementationOnce(() => {
|
mavenDatasource.getReleases.mockImplementationOnce(() => {
|
||||||
throw new DatasourceError(new Error());
|
throw new ExternalHostError(new Error());
|
||||||
});
|
});
|
||||||
await expect(
|
await expect(
|
||||||
datasource.getPkgReleases({
|
datasource.getPkgReleases({
|
||||||
|
@ -183,7 +183,7 @@ describe('datasource/index', () => {
|
||||||
depName: 'something',
|
depName: 'something',
|
||||||
registryUrls: ['https://reg1.com', 'https://reg2.io'],
|
registryUrls: ['https://reg1.com', 'https://reg2.io'],
|
||||||
})
|
})
|
||||||
).rejects.toThrow(DATASOURCE_FAILURE);
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
});
|
});
|
||||||
it('merges registries and passes on error', async () => {
|
it('merges registries and passes on error', async () => {
|
||||||
mavenDatasource.getReleases.mockImplementationOnce(() => {
|
mavenDatasource.getReleases.mockImplementationOnce(() => {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import is from '@sindresorhus/is';
|
import is from '@sindresorhus/is';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { logger } from '../logger';
|
import { logger } from '../logger';
|
||||||
|
import { ExternalHostError } from '../types/error';
|
||||||
import * as runCache from '../util/cache/run';
|
import * as runCache from '../util/cache/run';
|
||||||
import { clone } from '../util/clone';
|
import { clone } from '../util/clone';
|
||||||
import * as allVersioning from '../versioning';
|
import * as allVersioning from '../versioning';
|
||||||
import datasources from './api.generated';
|
import datasources from './api.generated';
|
||||||
import {
|
import {
|
||||||
Datasource,
|
Datasource,
|
||||||
DatasourceError,
|
|
||||||
DigestConfig,
|
DigestConfig,
|
||||||
GetPkgReleasesConfig,
|
GetPkgReleasesConfig,
|
||||||
GetReleasesConfig,
|
GetReleasesConfig,
|
||||||
|
@ -65,7 +65,7 @@ async function huntRegistries(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof DatasourceError) {
|
if (err instanceof ExternalHostError) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
// We'll always save the last-thrown error
|
// We'll always save the last-thrown error
|
||||||
|
@ -100,7 +100,7 @@ async function mergeRegistries(
|
||||||
combinedRes = res;
|
combinedRes = res;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof DatasourceError) {
|
if (err instanceof ExternalHostError) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
// We'll always save the last-thrown error
|
// We'll always save the last-thrown error
|
||||||
|
@ -221,8 +221,8 @@ export async function getPkgReleases(
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} catch (e) /* istanbul ignore next */ {
|
} catch (e) /* istanbul ignore next */ {
|
||||||
if (e instanceof DatasourceError) {
|
if (e instanceof ExternalHostError) {
|
||||||
e.datasource = config.datasource;
|
e.hostType = config.datasource;
|
||||||
e.lookupName = lookupName;
|
e.lookupName = lookupName;
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
|
|
|
@ -2,7 +2,7 @@ import fs from 'fs';
|
||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
import nock from 'nock';
|
import nock from 'nock';
|
||||||
import { getPkgReleases } from '..';
|
import { getPkgReleases } from '..';
|
||||||
import { DATASOURCE_FAILURE } from '../../constants/error-messages';
|
import { EXTERNAL_HOST_ERROR } from '../../constants/error-messages';
|
||||||
import * as hostRules from '../../util/host-rules';
|
import * as hostRules from '../../util/host-rules';
|
||||||
import * as mavenVersioning from '../../versioning/maven';
|
import * as mavenVersioning from '../../versioning/maven';
|
||||||
import { id as datasource } from '.';
|
import { id as datasource } from '.';
|
||||||
|
@ -182,7 +182,7 @@ describe('datasource/maven', () => {
|
||||||
expect(releases.releases).toEqual(generateReleases(MYSQL_VERSIONS));
|
expect(releases.releases).toEqual(generateReleases(MYSQL_VERSIONS));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw registry-failure if default maven repo fails', async () => {
|
it('should throw external-host-error if default maven repo fails', async () => {
|
||||||
nock('https://repo.maven.apache.org')
|
nock('https://repo.maven.apache.org')
|
||||||
.get('/maven2/org/artifact/maven-metadata.xml')
|
.get('/maven2/org/artifact/maven-metadata.xml')
|
||||||
.times(4)
|
.times(4)
|
||||||
|
@ -195,7 +195,7 @@ describe('datasource/maven', () => {
|
||||||
depName: 'org:artifact',
|
depName: 'org:artifact',
|
||||||
registryUrls: ['https://repo.maven.apache.org/maven2/'],
|
registryUrls: ['https://repo.maven.apache.org/maven2/'],
|
||||||
})
|
})
|
||||||
).rejects.toThrow(Error(DATASOURCE_FAILURE));
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return all versions of a specific library if a repository fails because invalid protocol', async () => {
|
it('should return all versions of a specific library if a repository fails because invalid protocol', async () => {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import url from 'url';
|
import url from 'url';
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import { Http } from '../../util/http';
|
import { Http } from '../../util/http';
|
||||||
import { DatasourceError } from '../common';
|
|
||||||
|
|
||||||
import { MAVEN_REPO, id } from './common';
|
import { MAVEN_REPO, id } from './common';
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ export async function downloadHttpProtocol(
|
||||||
} else if (isTemporalError(err)) {
|
} else if (isTemporalError(err)) {
|
||||||
logger.debug({ failedUrl, err }, 'Temporary error');
|
logger.debug({ failedUrl, err }, 'Temporary error');
|
||||||
if (isMavenCentral(pkgUrl)) {
|
if (isMavenCentral(pkgUrl)) {
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
} else if (isConnectionError(err)) {
|
} else if (isConnectionError(err)) {
|
||||||
// istanbul ignore next
|
// istanbul ignore next
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as httpMock from '../../../test/httpMock';
|
import * as httpMock from '../../../test/httpMock';
|
||||||
import { getName } from '../../../test/util';
|
import { getName } from '../../../test/util';
|
||||||
import { DatasourceError } from '../common';
|
import { ExternalHostError } from '../../types/error';
|
||||||
import { getDependency, resetMemCache } from './get';
|
import { getDependency, resetMemCache } from './get';
|
||||||
import { setNpmrc } from './npmrc';
|
import { setNpmrc } from './npmrc';
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ describe(getName(__filename), () => {
|
||||||
.get('/npm-parse-error')
|
.get('/npm-parse-error')
|
||||||
.reply(200, 'not-a-json');
|
.reply(200, 'not-a-json');
|
||||||
await expect(getDependency('npm-parse-error', 0)).rejects.toThrow(
|
await expect(getDependency('npm-parse-error', 0)).rejects.toThrow(
|
||||||
DatasourceError
|
ExternalHostError
|
||||||
);
|
);
|
||||||
|
|
||||||
httpMock
|
httpMock
|
||||||
|
|
|
@ -6,11 +6,12 @@ import moment from 'moment';
|
||||||
import registryAuthToken from 'registry-auth-token';
|
import registryAuthToken from 'registry-auth-token';
|
||||||
import getRegistryUrl from 'registry-auth-token/registry-url';
|
import getRegistryUrl from 'registry-auth-token/registry-url';
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import * as globalCache from '../../util/cache/global';
|
import * as globalCache from '../../util/cache/global';
|
||||||
import { find } from '../../util/host-rules';
|
import { find } from '../../util/host-rules';
|
||||||
import { Http, HttpOptions } from '../../util/http';
|
import { Http, HttpOptions } from '../../util/http';
|
||||||
import { maskToken } from '../../util/mask';
|
import { maskToken } from '../../util/mask';
|
||||||
import { DatasourceError, Release, ReleaseResult } from '../common';
|
import { Release, ReleaseResult } from '../common';
|
||||||
import { id } from './common';
|
import { id } from './common';
|
||||||
import { getNpmrc } from './npmrc';
|
import { getNpmrc } from './npmrc';
|
||||||
|
|
||||||
|
@ -280,7 +281,7 @@ export async function getDependency(
|
||||||
if (err.name === 'ParseError' && err.body) {
|
if (err.name === 'ParseError' && err.body) {
|
||||||
err.body = 'err.body deleted by Renovate';
|
err.body = 'err.body deleted by Renovate';
|
||||||
}
|
}
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import nock from 'nock';
|
||||||
import _registryAuthToken from 'registry-auth-token';
|
import _registryAuthToken from 'registry-auth-token';
|
||||||
import { getPkgReleases } from '..';
|
import { getPkgReleases } from '..';
|
||||||
import { getName } from '../../../test/util';
|
import { getName } from '../../../test/util';
|
||||||
import { DATASOURCE_FAILURE } from '../../constants/error-messages';
|
import { EXTERNAL_HOST_ERROR } from '../../constants/error-messages';
|
||||||
import * as hostRules from '../../util/host-rules';
|
import * as hostRules from '../../util/host-rules';
|
||||||
import { id as datasource, getNpmrc, resetCache, setNpmrc } from '.';
|
import { id as datasource, getNpmrc, resetCache, setNpmrc } from '.';
|
||||||
|
|
||||||
|
@ -204,13 +204,13 @@ describe(getName(__filename), () => {
|
||||||
nock('https://registry.npmjs.org').get('/foobar').reply(503);
|
nock('https://registry.npmjs.org').get('/foobar').reply(503);
|
||||||
await expect(
|
await expect(
|
||||||
getPkgReleases({ datasource, depName: 'foobar' })
|
getPkgReleases({ datasource, depName: 'foobar' })
|
||||||
).rejects.toThrow(Error(DATASOURCE_FAILURE));
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
});
|
});
|
||||||
it('should throw error for 408', async () => {
|
it('should throw error for 408', async () => {
|
||||||
nock('https://registry.npmjs.org').get('/foobar').reply(408);
|
nock('https://registry.npmjs.org').get('/foobar').reply(408);
|
||||||
await expect(
|
await expect(
|
||||||
getPkgReleases({ datasource, depName: 'foobar' })
|
getPkgReleases({ datasource, depName: 'foobar' })
|
||||||
).rejects.toThrow(Error(DATASOURCE_FAILURE));
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
});
|
});
|
||||||
it('should throw error for others', async () => {
|
it('should throw error for others', async () => {
|
||||||
nock('https://registry.npmjs.org').get('/foobar').reply(451);
|
nock('https://registry.npmjs.org').get('/foobar').reply(451);
|
||||||
|
|
|
@ -2,11 +2,12 @@ import URL from 'url';
|
||||||
|
|
||||||
import pAll from 'p-all';
|
import pAll from 'p-all';
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import * as globalCache from '../../util/cache/global';
|
import * as globalCache from '../../util/cache/global';
|
||||||
import * as runCache from '../../util/cache/run';
|
import * as runCache from '../../util/cache/run';
|
||||||
import * as hostRules from '../../util/host-rules';
|
import * as hostRules from '../../util/host-rules';
|
||||||
import { Http, HttpOptions } from '../../util/http';
|
import { Http, HttpOptions } from '../../util/http';
|
||||||
import { DatasourceError, GetReleasesConfig, ReleaseResult } from '../common';
|
import { GetReleasesConfig, ReleaseResult } from '../common';
|
||||||
|
|
||||||
export const id = 'packagist';
|
export const id = 'packagist';
|
||||||
export const defaultRegistryUrls = ['https://packagist.org'];
|
export const defaultRegistryUrls = ['https://packagist.org'];
|
||||||
|
@ -313,10 +314,10 @@ async function packageLookup(
|
||||||
}
|
}
|
||||||
if (err.host === 'packagist.org') {
|
if (err.host === 'packagist.org') {
|
||||||
if (err.code === 'ECONNRESET' || err.code === 'ETIMEDOUT') {
|
if (err.code === 'ECONNRESET' || err.code === 'ETIMEDOUT') {
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
if (err.statusCode && err.statusCode >= 500 && err.statusCode < 600) {
|
if (err.statusCode && err.statusCode >= 500 && err.statusCode < 600) {
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.warn({ err, name }, 'packagist registry failure: Unknown error');
|
logger.warn({ err, name }, 'packagist registry failure: Unknown error');
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { getPkgReleases } from '..';
|
import { getPkgReleases } from '..';
|
||||||
import * as httpMock from '../../../test/httpMock';
|
import * as httpMock from '../../../test/httpMock';
|
||||||
|
import { EXTERNAL_HOST_ERROR } from '../../constants/error-messages';
|
||||||
import * as rubyVersioning from '../../versioning/ruby';
|
import * as rubyVersioning from '../../versioning/ruby';
|
||||||
import * as pod from '.';
|
import * as pod from '.';
|
||||||
|
|
||||||
|
@ -63,7 +64,7 @@ describe('datasource/cocoapods', () => {
|
||||||
.scope(cocoapodsHost)
|
.scope(cocoapodsHost)
|
||||||
.get('/all_pods_versions_a_c_b.txt')
|
.get('/all_pods_versions_a_c_b.txt')
|
||||||
.reply(429);
|
.reply(429);
|
||||||
await expect(getPkgReleases(config)).rejects.toThrow('registry-failure');
|
await expect(getPkgReleases(config)).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
expect(httpMock.getTrace()).toMatchSnapshot();
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
it('returns null for unknown error', async () => {
|
it('returns null for unknown error', async () => {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import * as globalCache from '../../util/cache/global';
|
import * as globalCache from '../../util/cache/global';
|
||||||
import { Http } from '../../util/http';
|
import { Http } from '../../util/http';
|
||||||
import { GithubHttp } from '../../util/http/github';
|
import { GithubHttp } from '../../util/http/github';
|
||||||
|
@ -44,7 +45,7 @@ function handleError(lookupName: string, err: Error): void {
|
||||||
(err.statusCode >= 500 && err.statusCode < 600)
|
(err.statusCode >= 500 && err.statusCode < 600)
|
||||||
) {
|
) {
|
||||||
logger.warn({ lookupName, err }, `CocoaPods registry failure`);
|
logger.warn({ lookupName, err }, `CocoaPods registry failure`);
|
||||||
throw new Error('registry-failure');
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err.statusCode === 401) {
|
if (err.statusCode === 401) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import fs from 'fs';
|
||||||
import { getPkgReleases } from '..';
|
import { getPkgReleases } from '..';
|
||||||
import * as httpMock from '../../../test/httpMock';
|
import * as httpMock from '../../../test/httpMock';
|
||||||
import { getName } from '../../../test/util';
|
import { getName } from '../../../test/util';
|
||||||
import { DATASOURCE_FAILURE } from '../../constants/error-messages';
|
import { EXTERNAL_HOST_ERROR } from '../../constants/error-messages';
|
||||||
import { id as versioning } from '../../versioning/loose';
|
import { id as versioning } from '../../versioning/loose';
|
||||||
import { RepologyPackage, id as datasource } from '.';
|
import { RepologyPackage, id as datasource } from '.';
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ describe(getName(__filename), () => {
|
||||||
versioning,
|
versioning,
|
||||||
depName: 'debian_stable/nginx',
|
depName: 'debian_stable/nginx',
|
||||||
})
|
})
|
||||||
).rejects.toThrow(DATASOURCE_FAILURE);
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
expect(httpMock.getTrace()).toMatchSnapshot();
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ describe(getName(__filename), () => {
|
||||||
versioning,
|
versioning,
|
||||||
depName: 'debian_stable/nginx',
|
depName: 'debian_stable/nginx',
|
||||||
})
|
})
|
||||||
).rejects.toThrow(DATASOURCE_FAILURE);
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
expect(httpMock.getTrace()).toMatchSnapshot();
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ describe(getName(__filename), () => {
|
||||||
versioning,
|
versioning,
|
||||||
depName: 'invalid-lookup-name',
|
depName: 'invalid-lookup-name',
|
||||||
})
|
})
|
||||||
).rejects.toThrow(DATASOURCE_FAILURE);
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
expect(httpMock.getTrace()).toMatchSnapshot();
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { URLSearchParams } from 'url';
|
import { URLSearchParams } from 'url';
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import * as globalCache from '../../util/cache/global';
|
import * as globalCache from '../../util/cache/global';
|
||||||
import { Http } from '../../util/http';
|
import { Http } from '../../util/http';
|
||||||
import { DatasourceError, GetReleasesConfig, ReleaseResult } from '../common';
|
import { GetReleasesConfig, ReleaseResult } from '../common';
|
||||||
|
|
||||||
export const id = 'repology';
|
export const id = 'repology';
|
||||||
|
|
||||||
|
@ -117,7 +118,7 @@ export async function getReleases({
|
||||||
// Ensure lookup name contains both repository and package
|
// Ensure lookup name contains both repository and package
|
||||||
const [repoName, pkgName] = lookupName.split('/', 2);
|
const [repoName, pkgName] = lookupName.split('/', 2);
|
||||||
if (!repoName || !pkgName) {
|
if (!repoName || !pkgName) {
|
||||||
throw new DatasourceError(
|
throw new ExternalHostError(
|
||||||
new Error(
|
new Error(
|
||||||
'Repology lookup name must contain repository and package separated by slash (<repo>/<pkg>)'
|
'Repology lookup name must contain repository and package separated by slash (<repo>/<pkg>)'
|
||||||
)
|
)
|
||||||
|
@ -142,6 +143,6 @@ export async function getReleases({
|
||||||
{ lookupName, err },
|
{ lookupName, err },
|
||||||
'Repology lookup failed with unexpected error'
|
'Repology lookup failed with unexpected error'
|
||||||
);
|
);
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { parse } from 'node-html-parser';
|
import { parse } from 'node-html-parser';
|
||||||
|
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import * as globalCache from '../../util/cache/global';
|
import * as globalCache from '../../util/cache/global';
|
||||||
import { Http } from '../../util/http';
|
import { Http } from '../../util/http';
|
||||||
import { isVersion } from '../../versioning/ruby';
|
import { isVersion } from '../../versioning/ruby';
|
||||||
import { DatasourceError, GetReleasesConfig, ReleaseResult } from '../common';
|
import { GetReleasesConfig, ReleaseResult } from '../common';
|
||||||
|
|
||||||
export const id = 'ruby-version';
|
export const id = 'ruby-version';
|
||||||
|
|
||||||
|
@ -51,6 +52,6 @@ export async function getReleases(
|
||||||
await globalCache.set(cacheNamespace, 'all', res, 15);
|
await globalCache.set(cacheNamespace, 'all', res, 15);
|
||||||
return res;
|
return res;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import { Http } from '../../util/http';
|
import { Http } from '../../util/http';
|
||||||
import { DatasourceError, ReleaseResult } from '../common';
|
import { ReleaseResult } from '../common';
|
||||||
import { id } from './common';
|
import { id } from './common';
|
||||||
|
|
||||||
const http = new Http(id);
|
const http = new Http(id);
|
||||||
|
@ -38,7 +39,7 @@ async function updateRubyGemsVersions(): Promise<void> {
|
||||||
if (err.statusCode !== 416) {
|
if (err.statusCode !== 416) {
|
||||||
contentLength = 0;
|
contentLength = 0;
|
||||||
packageReleases = Object.create(null); // Because we might need a "constructor" key
|
packageReleases = Object.create(null); // Because we might need a "constructor" key
|
||||||
throw new DatasourceError(
|
throw new ExternalHostError(
|
||||||
new Error('Rubygems fetch error - need to reset cache')
|
new Error('Rubygems fetch error - need to reset cache')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import * as globalCache from '../../util/cache/global';
|
import * as globalCache from '../../util/cache/global';
|
||||||
import { Http } from '../../util/http';
|
import { Http } from '../../util/http';
|
||||||
import { DatasourceError, GetReleasesConfig, ReleaseResult } from '../common';
|
import { GetReleasesConfig, ReleaseResult } from '../common';
|
||||||
|
|
||||||
export const id = 'terraform-module';
|
export const id = 'terraform-module';
|
||||||
export const defaultRegistryUrls = ['https://registry.terraform.io'];
|
export const defaultRegistryUrls = ['https://registry.terraform.io'];
|
||||||
|
@ -113,7 +114,7 @@ export async function getReleases({
|
||||||
const failureCodes = ['EAI_AGAIN'];
|
const failureCodes = ['EAI_AGAIN'];
|
||||||
// istanbul ignore if
|
// istanbul ignore if
|
||||||
if (failureCodes.includes(err.code)) {
|
if (failureCodes.includes(err.code)) {
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err);
|
||||||
}
|
}
|
||||||
logger.warn(
|
logger.warn(
|
||||||
{ err, lookupName },
|
{ err, lookupName },
|
||||||
|
|
|
@ -3,9 +3,9 @@ import * as os from 'os';
|
||||||
import * as fs from 'fs-extra';
|
import * as fs from 'fs-extra';
|
||||||
import upath from 'upath';
|
import upath from 'upath';
|
||||||
import { LANGUAGE_JAVA } from '../../constants/languages';
|
import { LANGUAGE_JAVA } from '../../constants/languages';
|
||||||
import { DatasourceError } from '../../datasource';
|
|
||||||
import * as datasourceMaven from '../../datasource/maven';
|
import * as datasourceMaven from '../../datasource/maven';
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import { ExecOptions, exec } from '../../util/exec';
|
import { ExecOptions, exec } from '../../util/exec';
|
||||||
import { BinarySource } from '../../util/exec/common';
|
import { BinarySource } from '../../util/exec/common';
|
||||||
import { readLocalFile } from '../../util/fs';
|
import { readLocalFile } from '../../util/fs';
|
||||||
|
@ -106,9 +106,7 @@ export async function executeGradle(
|
||||||
({ stdout, stderr } = await exec(cmd, execOptions));
|
({ stdout, stderr } = await exec(cmd, execOptions));
|
||||||
} catch (err) /* istanbul ignore next */ {
|
} catch (err) /* istanbul ignore next */ {
|
||||||
if (err.code === TIMEOUT_CODE) {
|
if (err.code === TIMEOUT_CODE) {
|
||||||
const error = new DatasourceError(err);
|
throw new ExternalHostError(err, 'gradle');
|
||||||
error.datasource = 'gradle';
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
logger.warn({ errMessage: err.message }, 'Gradle extraction failed');
|
logger.warn({ errMessage: err.message }, 'Gradle extraction failed');
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -3,9 +3,10 @@ import fs from 'fs-extra';
|
||||||
import upath from 'upath';
|
import upath from 'upath';
|
||||||
// eslint-disable-next-line import/no-unresolved
|
// eslint-disable-next-line import/no-unresolved
|
||||||
import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../../constants/error-messages';
|
import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../../constants/error-messages';
|
||||||
import { DatasourceError } from '../../../datasource/common';
|
import { id as npmId } from '../../../datasource/npm';
|
||||||
import { logger } from '../../../logger';
|
import { logger } from '../../../logger';
|
||||||
import { platform } from '../../../platform';
|
import { platform } from '../../../platform';
|
||||||
|
import { ExternalHostError } from '../../../types/error';
|
||||||
import { getChildProcessEnv } from '../../../util/exec/env';
|
import { getChildProcessEnv } from '../../../util/exec/env';
|
||||||
import { deleteLocalFile } from '../../../util/fs';
|
import { deleteLocalFile } from '../../../util/fs';
|
||||||
import * as hostRules from '../../../util/host-rules';
|
import * as hostRules from '../../../util/host-rules';
|
||||||
|
@ -432,7 +433,7 @@ export async function getAdditionalFiles(
|
||||||
const err = new Error(
|
const err = new Error(
|
||||||
'lock file failed for the dependency being updated - skipping branch creation'
|
'lock file failed for the dependency being updated - skipping branch creation'
|
||||||
);
|
);
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err, npmId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -492,10 +493,11 @@ export async function getAdditionalFiles(
|
||||||
{ dependency: upgrade.depName, type: 'yarn' },
|
{ dependency: upgrade.depName, type: 'yarn' },
|
||||||
'lock file failed for the dependency being updated - skipping branch creation'
|
'lock file failed for the dependency being updated - skipping branch creation'
|
||||||
);
|
);
|
||||||
throw new DatasourceError(
|
throw new ExternalHostError(
|
||||||
new Error(
|
new Error(
|
||||||
'lock file failed for the dependency being updated - skipping branch creation'
|
'lock file failed for the dependency being updated - skipping branch creation'
|
||||||
)
|
),
|
||||||
|
npmId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/* eslint-enable no-useless-escape */
|
/* eslint-enable no-useless-escape */
|
||||||
|
@ -594,10 +596,11 @@ export async function getAdditionalFiles(
|
||||||
{ dependency: upgrade.depName, type: 'pnpm' },
|
{ dependency: upgrade.depName, type: 'pnpm' },
|
||||||
'lock file failed for the dependency being updated - skipping branch creation'
|
'lock file failed for the dependency being updated - skipping branch creation'
|
||||||
);
|
);
|
||||||
throw new DatasourceError(
|
throw new ExternalHostError(
|
||||||
Error(
|
Error(
|
||||||
'lock file failed for the dependency being updated - skipping branch creation'
|
'lock file failed for the dependency being updated - skipping branch creation'
|
||||||
)
|
),
|
||||||
|
npmId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -672,10 +675,11 @@ export async function getAdditionalFiles(
|
||||||
{ dependency: upgrade.depName, type: 'yarn' },
|
{ dependency: upgrade.depName, type: 'yarn' },
|
||||||
'lock file failed for the dependency being updated - skipping branch creation'
|
'lock file failed for the dependency being updated - skipping branch creation'
|
||||||
);
|
);
|
||||||
throw new DatasourceError(
|
throw new ExternalHostError(
|
||||||
Error(
|
Error(
|
||||||
'lock file failed for the dependency being updated - skipping branch creation'
|
'lock file failed for the dependency being updated - skipping branch creation'
|
||||||
)
|
),
|
||||||
|
npmId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/* eslint-enable no-useless-escape */
|
/* eslint-enable no-useless-escape */
|
||||||
|
@ -688,10 +692,11 @@ export async function getAdditionalFiles(
|
||||||
{ dependency: upgrade.depName, type: 'npm' },
|
{ dependency: upgrade.depName, type: 'npm' },
|
||||||
'lock file failed for the dependency being updated - skipping branch creation'
|
'lock file failed for the dependency being updated - skipping branch creation'
|
||||||
);
|
);
|
||||||
throw new DatasourceError(
|
throw new ExternalHostError(
|
||||||
Error(
|
Error(
|
||||||
'lock file failed for the dependency being updated - skipping branch creation'
|
'lock file failed for the dependency being updated - skipping branch creation'
|
||||||
)
|
),
|
||||||
|
npmId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,9 @@ import { validRange } from 'semver';
|
||||||
import { quote } from 'shlex';
|
import { quote } from 'shlex';
|
||||||
import { join } from 'upath';
|
import { join } from 'upath';
|
||||||
import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../../constants/error-messages';
|
import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../../constants/error-messages';
|
||||||
import { DatasourceError } from '../../../datasource';
|
import { id as npmId } from '../../../datasource/npm';
|
||||||
import { logger } from '../../../logger';
|
import { logger } from '../../../logger';
|
||||||
|
import { ExternalHostError } from '../../../types/error';
|
||||||
import { ExecOptions, exec } from '../../../util/exec';
|
import { ExecOptions, exec } from '../../../util/exec';
|
||||||
import { PostUpdateConfig, Upgrade } from '../../common';
|
import { PostUpdateConfig, Upgrade } from '../../common';
|
||||||
import { getNodeConstraint } from './node-version';
|
import { getNodeConstraint } from './node-version';
|
||||||
|
@ -151,7 +152,7 @@ export async function generateLockFile(
|
||||||
err.stderr.includes('getaddrinfo ENOTFOUND registry.yarnpkg.com') ||
|
err.stderr.includes('getaddrinfo ENOTFOUND registry.yarnpkg.com') ||
|
||||||
err.stderr.includes('getaddrinfo ENOTFOUND registry.npmjs.org')
|
err.stderr.includes('getaddrinfo ENOTFOUND registry.npmjs.org')
|
||||||
) {
|
) {
|
||||||
throw new DatasourceError(err);
|
throw new ExternalHostError(err, npmId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { error: true, stderr: err.stderr };
|
return { error: true, stderr: err.stderr };
|
||||||
|
|
|
@ -4,13 +4,13 @@ import fs from 'fs-extra';
|
||||||
import Git from 'simple-git/promise';
|
import Git from 'simple-git/promise';
|
||||||
import {
|
import {
|
||||||
CONFIG_VALIDATION,
|
CONFIG_VALIDATION,
|
||||||
PLATFORM_FAILURE,
|
|
||||||
REPOSITORY_CHANGED,
|
REPOSITORY_CHANGED,
|
||||||
REPOSITORY_EMPTY,
|
REPOSITORY_EMPTY,
|
||||||
REPOSITORY_TEMPORARY_ERROR,
|
REPOSITORY_TEMPORARY_ERROR,
|
||||||
SYSTEM_INSUFFICIENT_DISK_SPACE,
|
SYSTEM_INSUFFICIENT_DISK_SPACE,
|
||||||
} from '../../constants/error-messages';
|
} from '../../constants/error-messages';
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import * as limits from '../../workers/global/limits';
|
import * as limits from '../../workers/global/limits';
|
||||||
import { CommitFilesConfig } from '../common';
|
import { CommitFilesConfig } from '../common';
|
||||||
import { writePrivateKey } from './private-key';
|
import { writePrivateKey } from './private-key';
|
||||||
|
@ -54,7 +54,7 @@ function checkForPlatformFailure(err: Error): void {
|
||||||
];
|
];
|
||||||
for (const errorStr of platformFailureStrings) {
|
for (const errorStr of platformFailureStrings) {
|
||||||
if (err.message.includes(errorStr)) {
|
if (err.message.includes(errorStr)) {
|
||||||
throw new Error(PLATFORM_FAILURE);
|
throw new ExternalHostError(err, 'git');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ export class Storage {
|
||||||
if (err.message?.includes('write error: No space left on device')) {
|
if (err.message?.includes('write error: No space left on device')) {
|
||||||
throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE);
|
throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE);
|
||||||
}
|
}
|
||||||
throw new Error(PLATFORM_FAILURE);
|
throw new ExternalHostError(err, 'git');
|
||||||
}
|
}
|
||||||
const durationMs = Math.round(Date.now() - cloneStart);
|
const durationMs = Math.round(Date.now() - cloneStart);
|
||||||
logger.debug({ durationMs }, 'git clone completed');
|
logger.debug({ durationMs }, 'git clone completed');
|
||||||
|
|
|
@ -3,7 +3,6 @@ import is from '@sindresorhus/is';
|
||||||
import delay from 'delay';
|
import delay from 'delay';
|
||||||
import { configFileNames } from '../../config/app-strings';
|
import { configFileNames } from '../../config/app-strings';
|
||||||
import {
|
import {
|
||||||
PLATFORM_FAILURE,
|
|
||||||
PLATFORM_INTEGRATION_UNAUTHORIZED,
|
PLATFORM_INTEGRATION_UNAUTHORIZED,
|
||||||
REPOSITORY_ACCESS_FORBIDDEN,
|
REPOSITORY_ACCESS_FORBIDDEN,
|
||||||
REPOSITORY_ARCHIVED,
|
REPOSITORY_ARCHIVED,
|
||||||
|
@ -24,6 +23,7 @@ import {
|
||||||
} from '../../constants/pull-requests';
|
} from '../../constants/pull-requests';
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
import { BranchStatus } from '../../types';
|
import { BranchStatus } from '../../types';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import * as hostRules from '../../util/host-rules';
|
import * as hostRules from '../../util/host-rules';
|
||||||
import * as githubHttp from '../../util/http/github';
|
import * as githubHttp from '../../util/http/github';
|
||||||
import { sanitize } from '../../util/sanitize';
|
import { sanitize } from '../../util/sanitize';
|
||||||
|
@ -397,7 +397,7 @@ export async function initRepo({
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (err) /* istanbul ignore next */ {
|
} catch (err) /* istanbul ignore next */ {
|
||||||
if (err.message === PLATFORM_FAILURE) {
|
if (err instanceof ExternalHostError) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
|
@ -965,7 +965,7 @@ export async function getPrList(): Promise<Pr[]> {
|
||||||
);
|
);
|
||||||
} catch (err) /* istanbul ignore next */ {
|
} catch (err) /* istanbul ignore next */ {
|
||||||
logger.debug({ err }, 'getPrList err');
|
logger.debug({ err }, 'getPrList err');
|
||||||
throw new Error('platform-failure');
|
throw new ExternalHostError(err, PLATFORM_TYPE_GITHUB);
|
||||||
}
|
}
|
||||||
config.prList = res.body.map((pr) => ({
|
config.prList = res.body.map((pr) => ({
|
||||||
number: pr.number,
|
number: pr.number,
|
||||||
|
@ -1094,7 +1094,7 @@ export async function getBranchStatus(
|
||||||
logger.debug({ result: checkRunsRaw }, 'No check runs found');
|
logger.debug({ result: checkRunsRaw }, 'No check runs found');
|
||||||
}
|
}
|
||||||
} catch (err) /* istanbul ignore next */ {
|
} catch (err) /* istanbul ignore next */ {
|
||||||
if (err.message === PLATFORM_FAILURE) {
|
if (err instanceof ExternalHostError) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
|
@ -1506,7 +1506,7 @@ async function getComments(issueNo: number): Promise<Comment[]> {
|
||||||
} catch (err) /* istanbul ignore next */ {
|
} catch (err) /* istanbul ignore next */ {
|
||||||
if (err.statusCode === 404) {
|
if (err.statusCode === 404) {
|
||||||
logger.debug('404 respose when retrieving comments');
|
logger.debug('404 respose when retrieving comments');
|
||||||
throw new Error(PLATFORM_FAILURE);
|
throw new ExternalHostError(err, PLATFORM_TYPE_GITHUB);
|
||||||
}
|
}
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
@ -1559,7 +1559,7 @@ export async function ensureComment({
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} catch (err) /* istanbul ignore next */ {
|
} catch (err) /* istanbul ignore next */ {
|
||||||
if (err.message === PLATFORM_FAILURE) {
|
if (err instanceof ExternalHostError) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
if (err.body?.message?.includes('is locked')) {
|
if (err.body?.message?.includes('is locked')) {
|
||||||
|
@ -1690,7 +1690,7 @@ export async function updatePr(
|
||||||
);
|
);
|
||||||
logger.debug({ pr: prNo }, 'PR updated');
|
logger.debug({ pr: prNo }, 'PR updated');
|
||||||
} catch (err) /* istanbul ignore next */ {
|
} catch (err) /* istanbul ignore next */ {
|
||||||
if (err.message === PLATFORM_FAILURE) {
|
if (err instanceof ExternalHostError) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
logger.warn({ err }, 'Error updating PR');
|
logger.warn({ err }, 'Error updating PR');
|
||||||
|
|
19
lib/types/error.ts
Normal file
19
lib/types/error.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { EXTERNAL_HOST_ERROR } from '../constants/error-messages';
|
||||||
|
|
||||||
|
export class ExternalHostError extends Error {
|
||||||
|
hostType: string;
|
||||||
|
|
||||||
|
err: Error;
|
||||||
|
|
||||||
|
lookupName?: string;
|
||||||
|
|
||||||
|
reason?: string;
|
||||||
|
|
||||||
|
constructor(err: Error, hostType?: string) {
|
||||||
|
super(EXTERNAL_HOST_ERROR);
|
||||||
|
// Set the prototype explicitly: https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
||||||
|
Object.setPrototypeOf(this, ExternalHostError.prototype);
|
||||||
|
this.hostType = hostType;
|
||||||
|
this.err = err;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,8 +2,8 @@ import delay from 'delay';
|
||||||
import * as httpMock from '../../../test/httpMock';
|
import * as httpMock from '../../../test/httpMock';
|
||||||
import { getName } from '../../../test/util';
|
import { getName } from '../../../test/util';
|
||||||
import {
|
import {
|
||||||
|
EXTERNAL_HOST_ERROR,
|
||||||
PLATFORM_BAD_CREDENTIALS,
|
PLATFORM_BAD_CREDENTIALS,
|
||||||
PLATFORM_FAILURE,
|
|
||||||
PLATFORM_INTEGRATION_UNAUTHORIZED,
|
PLATFORM_INTEGRATION_UNAUTHORIZED,
|
||||||
PLATFORM_RATE_LIMIT_EXCEEDED,
|
PLATFORM_RATE_LIMIT_EXCEEDED,
|
||||||
REPOSITORY_CHANGED,
|
REPOSITORY_CHANGED,
|
||||||
|
@ -126,7 +126,7 @@ describe(getName(__filename), () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
expect(e).toBeDefined();
|
expect(e).toBeDefined();
|
||||||
expect(e.message).toEqual(PLATFORM_FAILURE);
|
expect(e.message).toEqual(EXTERNAL_HOST_ERROR);
|
||||||
});
|
});
|
||||||
it('should throw platform failure for ENOTFOUND, ETIMEDOUT or EAI_AGAIN', () => {
|
it('should throw platform failure for ENOTFOUND, ETIMEDOUT or EAI_AGAIN', () => {
|
||||||
const codes = ['ENOTFOUND', 'ETIMEDOUT', 'EAI_AGAIN'];
|
const codes = ['ENOTFOUND', 'ETIMEDOUT', 'EAI_AGAIN'];
|
||||||
|
@ -137,7 +137,7 @@ describe(getName(__filename), () => {
|
||||||
code,
|
code,
|
||||||
});
|
});
|
||||||
expect(e).toBeDefined();
|
expect(e).toBeDefined();
|
||||||
expect(e.message).toEqual(PLATFORM_FAILURE);
|
expect(e.message).toEqual(EXTERNAL_HOST_ERROR);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it('should throw platform failure for 500', () => {
|
it('should throw platform failure for 500', () => {
|
||||||
|
@ -146,14 +146,14 @@ describe(getName(__filename), () => {
|
||||||
message: 'Internal Server Error',
|
message: 'Internal Server Error',
|
||||||
});
|
});
|
||||||
expect(e).toBeDefined();
|
expect(e).toBeDefined();
|
||||||
expect(e.message).toEqual(PLATFORM_FAILURE);
|
expect(e.message).toEqual(EXTERNAL_HOST_ERROR);
|
||||||
});
|
});
|
||||||
it('should throw platform failure ParseError', () => {
|
it('should throw platform failure ParseError', () => {
|
||||||
const e = getError({
|
const e = getError({
|
||||||
name: 'ParseError',
|
name: 'ParseError',
|
||||||
});
|
});
|
||||||
expect(e).toBeDefined();
|
expect(e).toBeDefined();
|
||||||
expect(e.message).toEqual(PLATFORM_FAILURE);
|
expect(e.message).toEqual(EXTERNAL_HOST_ERROR);
|
||||||
});
|
});
|
||||||
it('should throw for unauthorized integration', () => {
|
it('should throw for unauthorized integration', () => {
|
||||||
const e = getError({
|
const e = getError({
|
||||||
|
@ -200,7 +200,7 @@ describe(getName(__filename), () => {
|
||||||
};
|
};
|
||||||
const e = getError(gotErr);
|
const e = getError(gotErr);
|
||||||
expect(e).toBeDefined();
|
expect(e).toBeDefined();
|
||||||
expect(e.message).toEqual(PLATFORM_FAILURE);
|
expect(e.message).toEqual(EXTERNAL_HOST_ERROR);
|
||||||
});
|
});
|
||||||
it('should throw original error when failed to add reviewers', () => {
|
it('should throw original error when failed to add reviewers', () => {
|
||||||
const gotErr = {
|
const gotErr = {
|
||||||
|
|
|
@ -4,13 +4,13 @@ import pAll from 'p-all';
|
||||||
import parseLinkHeader from 'parse-link-header';
|
import parseLinkHeader from 'parse-link-header';
|
||||||
import {
|
import {
|
||||||
PLATFORM_BAD_CREDENTIALS,
|
PLATFORM_BAD_CREDENTIALS,
|
||||||
PLATFORM_FAILURE,
|
|
||||||
PLATFORM_INTEGRATION_UNAUTHORIZED,
|
PLATFORM_INTEGRATION_UNAUTHORIZED,
|
||||||
PLATFORM_RATE_LIMIT_EXCEEDED,
|
PLATFORM_RATE_LIMIT_EXCEEDED,
|
||||||
REPOSITORY_CHANGED,
|
REPOSITORY_CHANGED,
|
||||||
} from '../../constants/error-messages';
|
} from '../../constants/error-messages';
|
||||||
import { PLATFORM_TYPE_GITHUB } from '../../constants/platforms';
|
import { PLATFORM_TYPE_GITHUB } from '../../constants/platforms';
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import { maskToken } from '../mask';
|
import { maskToken } from '../mask';
|
||||||
import { Http, HttpPostOptions, HttpResponse, InternalHttpOptions } from '.';
|
import { Http, HttpPostOptions, HttpResponse, InternalHttpOptions } from '.';
|
||||||
|
|
||||||
|
@ -61,15 +61,15 @@ export function handleGotError(
|
||||||
err.code === 'EAI_AGAIN')
|
err.code === 'EAI_AGAIN')
|
||||||
) {
|
) {
|
||||||
logger.debug({ err }, 'GitHub failure: RequestError');
|
logger.debug({ err }, 'GitHub failure: RequestError');
|
||||||
throw new Error(PLATFORM_FAILURE);
|
throw new ExternalHostError(err, PLATFORM_TYPE_GITHUB);
|
||||||
}
|
}
|
||||||
if (err.name === 'ParseError') {
|
if (err.name === 'ParseError') {
|
||||||
logger.debug({ err }, '');
|
logger.debug({ err }, '');
|
||||||
throw new Error(PLATFORM_FAILURE);
|
throw new ExternalHostError(err, PLATFORM_TYPE_GITHUB);
|
||||||
}
|
}
|
||||||
if (err.statusCode >= 500 && err.statusCode < 600) {
|
if (err.statusCode >= 500 && err.statusCode < 600) {
|
||||||
logger.debug({ err }, 'GitHub failure: 5xx');
|
logger.debug({ err }, 'GitHub failure: 5xx');
|
||||||
throw new Error(PLATFORM_FAILURE);
|
throw new ExternalHostError(err, PLATFORM_TYPE_GITHUB);
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
err.statusCode === 403 &&
|
err.statusCode === 403 &&
|
||||||
|
@ -106,7 +106,7 @@ export function handleGotError(
|
||||||
'GitHub failure: Bad credentials'
|
'GitHub failure: Bad credentials'
|
||||||
);
|
);
|
||||||
if (rateLimit === '60') {
|
if (rateLimit === '60') {
|
||||||
throw new Error(PLATFORM_FAILURE);
|
throw new ExternalHostError(err, PLATFORM_TYPE_GITHUB);
|
||||||
}
|
}
|
||||||
throw new Error(PLATFORM_BAD_CREDENTIALS);
|
throw new Error(PLATFORM_BAD_CREDENTIALS);
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ export function handleGotError(
|
||||||
throw new Error(REPOSITORY_CHANGED);
|
throw new Error(REPOSITORY_CHANGED);
|
||||||
}
|
}
|
||||||
logger.debug({ err }, '422 Error thrown from GitHub');
|
logger.debug({ err }, '422 Error thrown from GitHub');
|
||||||
throw new Error(PLATFORM_FAILURE);
|
throw new ExternalHostError(err, PLATFORM_TYPE_GITHUB);
|
||||||
}
|
}
|
||||||
if (err.statusCode === 404) {
|
if (err.statusCode === 404) {
|
||||||
logger.debug({ url: err.url }, 'GitHub 404');
|
logger.debug({ url: err.url }, 'GitHub 404');
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { URL } from 'url';
|
import { URL } from 'url';
|
||||||
import parseLinkHeader from 'parse-link-header';
|
import parseLinkHeader from 'parse-link-header';
|
||||||
import { PLATFORM_FAILURE } from '../../constants/error-messages';
|
|
||||||
import { PLATFORM_TYPE_GITLAB } from '../../constants/platforms';
|
import { PLATFORM_TYPE_GITLAB } from '../../constants/platforms';
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import { Http, HttpResponse, InternalHttpOptions } from '.';
|
import { Http, HttpResponse, InternalHttpOptions } from '.';
|
||||||
|
|
||||||
let baseUrl = 'https://gitlab.com/api/v4/';
|
let baseUrl = 'https://gitlab.com/api/v4/';
|
||||||
|
@ -63,7 +63,7 @@ export class GitlabHttp extends Http<GitlabHttpOptions, GitlabHttpOptions> {
|
||||||
err.statusCode === 429 ||
|
err.statusCode === 429 ||
|
||||||
(err.statusCode >= 500 && err.statusCode < 600)
|
(err.statusCode >= 500 && err.statusCode < 600)
|
||||||
) {
|
) {
|
||||||
throw new Error(PLATFORM_FAILURE);
|
throw new ExternalHostError(err, PLATFORM_TYPE_GITLAB);
|
||||||
}
|
}
|
||||||
const platformFailureCodes = [
|
const platformFailureCodes = [
|
||||||
'EAI_AGAIN',
|
'EAI_AGAIN',
|
||||||
|
@ -72,10 +72,10 @@ export class GitlabHttp extends Http<GitlabHttpOptions, GitlabHttpOptions> {
|
||||||
'UNABLE_TO_VERIFY_LEAF_SIGNATURE',
|
'UNABLE_TO_VERIFY_LEAF_SIGNATURE',
|
||||||
];
|
];
|
||||||
if (platformFailureCodes.includes(err.code)) {
|
if (platformFailureCodes.includes(err.code)) {
|
||||||
throw new Error(PLATFORM_FAILURE);
|
throw new ExternalHostError(err, PLATFORM_TYPE_GITLAB);
|
||||||
}
|
}
|
||||||
if (err.name === 'ParseError') {
|
if (err.name === 'ParseError') {
|
||||||
throw new Error(PLATFORM_FAILURE);
|
throw new ExternalHostError(err, PLATFORM_TYPE_GITLAB);
|
||||||
}
|
}
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,9 @@ import { DateTime } from 'luxon';
|
||||||
import minimatch from 'minimatch';
|
import minimatch from 'minimatch';
|
||||||
import { RenovateConfig } from '../../config';
|
import { RenovateConfig } from '../../config';
|
||||||
import {
|
import {
|
||||||
DATASOURCE_FAILURE,
|
|
||||||
MANAGER_LOCKFILE_ERROR,
|
MANAGER_LOCKFILE_ERROR,
|
||||||
PLATFORM_AUTHENTICATION_ERROR,
|
PLATFORM_AUTHENTICATION_ERROR,
|
||||||
PLATFORM_BAD_CREDENTIALS,
|
PLATFORM_BAD_CREDENTIALS,
|
||||||
PLATFORM_FAILURE,
|
|
||||||
PLATFORM_INTEGRATION_UNAUTHORIZED,
|
PLATFORM_INTEGRATION_UNAUTHORIZED,
|
||||||
PLATFORM_RATE_LIMIT_EXCEEDED,
|
PLATFORM_RATE_LIMIT_EXCEEDED,
|
||||||
REPOSITORY_CHANGED,
|
REPOSITORY_CHANGED,
|
||||||
|
@ -24,6 +22,7 @@ import { logger } from '../../logger';
|
||||||
import { getAdditionalFiles } from '../../manager/npm/post-update';
|
import { getAdditionalFiles } from '../../manager/npm/post-update';
|
||||||
import { platform } from '../../platform';
|
import { platform } from '../../platform';
|
||||||
import { BranchStatus } from '../../types';
|
import { BranchStatus } from '../../types';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import { emojify } from '../../util/emoji';
|
import { emojify } from '../../util/emoji';
|
||||||
import { exec } from '../../util/exec';
|
import { exec } from '../../util/exec';
|
||||||
import { readLocalFile, writeLocalFile } from '../../util/fs';
|
import { readLocalFile, writeLocalFile } from '../../util/fs';
|
||||||
|
@ -541,10 +540,7 @@ export async function processBranch(
|
||||||
err.message.includes('fatal: Authentication failed')
|
err.message.includes('fatal: Authentication failed')
|
||||||
) {
|
) {
|
||||||
throw new Error(PLATFORM_AUTHENTICATION_ERROR);
|
throw new Error(PLATFORM_AUTHENTICATION_ERROR);
|
||||||
} else if (
|
} else if (!(err instanceof ExternalHostError)) {
|
||||||
err.message !== DATASOURCE_FAILURE &&
|
|
||||||
err.message !== PLATFORM_FAILURE
|
|
||||||
) {
|
|
||||||
logger.error({ err }, `Error updating branch: ${err.message}`);
|
logger.error({ err }, `Error updating branch: ${err.message}`);
|
||||||
}
|
}
|
||||||
// Don't throw here - we don't want to stop the other renovations
|
// Don't throw here - we don't want to stop the other renovations
|
||||||
|
@ -655,11 +651,8 @@ export async function processBranch(
|
||||||
}
|
}
|
||||||
} catch (err) /* istanbul ignore next */ {
|
} catch (err) /* istanbul ignore next */ {
|
||||||
if (
|
if (
|
||||||
[
|
err instanceof ExternalHostError ||
|
||||||
PLATFORM_RATE_LIMIT_EXCEEDED,
|
[PLATFORM_RATE_LIMIT_EXCEEDED, REPOSITORY_CHANGED].includes(err.message)
|
||||||
PLATFORM_FAILURE,
|
|
||||||
REPOSITORY_CHANGED,
|
|
||||||
].includes(err.message)
|
|
||||||
) {
|
) {
|
||||||
logger.debug('Passing PR error up');
|
logger.debug('Passing PR error up');
|
||||||
throw err;
|
throw err;
|
||||||
|
|
|
@ -2,7 +2,6 @@ import sampleSize from 'lodash/sampleSize';
|
||||||
import uniq from 'lodash/uniq';
|
import uniq from 'lodash/uniq';
|
||||||
import { RenovateConfig } from '../../config/common';
|
import { RenovateConfig } from '../../config/common';
|
||||||
import {
|
import {
|
||||||
PLATFORM_FAILURE,
|
|
||||||
PLATFORM_INTEGRATION_UNAUTHORIZED,
|
PLATFORM_INTEGRATION_UNAUTHORIZED,
|
||||||
PLATFORM_RATE_LIMIT_EXCEEDED,
|
PLATFORM_RATE_LIMIT_EXCEEDED,
|
||||||
REPOSITORY_CHANGED,
|
REPOSITORY_CHANGED,
|
||||||
|
@ -10,6 +9,7 @@ import {
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
import { PlatformPrOptions, Pr, platform } from '../../platform';
|
import { PlatformPrOptions, Pr, platform } from '../../platform';
|
||||||
import { BranchStatus } from '../../types';
|
import { BranchStatus } from '../../types';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import { BranchConfig, PrResult } from '../common';
|
import { BranchConfig, PrResult } from '../common';
|
||||||
import { getPrBody } from './body';
|
import { getPrBody } from './body';
|
||||||
import { ChangeLogError } from './changelog';
|
import { ChangeLogError } from './changelog';
|
||||||
|
@ -427,9 +427,9 @@ export async function ensurePr(
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// istanbul ignore if
|
// istanbul ignore if
|
||||||
if (
|
if (
|
||||||
|
err instanceof ExternalHostError ||
|
||||||
err.message === REPOSITORY_CHANGED ||
|
err.message === REPOSITORY_CHANGED ||
|
||||||
err.message === PLATFORM_RATE_LIMIT_EXCEEDED ||
|
err.message === PLATFORM_RATE_LIMIT_EXCEEDED ||
|
||||||
err.message === PLATFORM_FAILURE ||
|
|
||||||
err.message === PLATFORM_INTEGRATION_UNAUTHORIZED
|
err.message === PLATFORM_INTEGRATION_UNAUTHORIZED
|
||||||
) {
|
) {
|
||||||
logger.debug('Passing error up');
|
logger.debug('Passing error up');
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import { RenovateConfig, getConfig } from '../../../test/util';
|
import { RenovateConfig, getConfig } from '../../../test/util';
|
||||||
import {
|
import {
|
||||||
CONFIG_VALIDATION,
|
CONFIG_VALIDATION,
|
||||||
DATASOURCE_FAILURE,
|
EXTERNAL_HOST_ERROR,
|
||||||
MANAGER_LOCKFILE_ERROR,
|
MANAGER_LOCKFILE_ERROR,
|
||||||
MANAGER_NO_PACKAGE_FILES,
|
MANAGER_NO_PACKAGE_FILES,
|
||||||
PLATFORM_AUTHENTICATION_ERROR,
|
PLATFORM_AUTHENTICATION_ERROR,
|
||||||
PLATFORM_BAD_CREDENTIALS,
|
PLATFORM_BAD_CREDENTIALS,
|
||||||
PLATFORM_FAILURE,
|
|
||||||
PLATFORM_INTEGRATION_UNAUTHORIZED,
|
PLATFORM_INTEGRATION_UNAUTHORIZED,
|
||||||
PLATFORM_RATE_LIMIT_EXCEEDED,
|
PLATFORM_RATE_LIMIT_EXCEEDED,
|
||||||
REPOSITORY_ACCESS_FORBIDDEN,
|
REPOSITORY_ACCESS_FORBIDDEN,
|
||||||
|
@ -27,7 +26,7 @@ import {
|
||||||
SYSTEM_INSUFFICIENT_MEMORY,
|
SYSTEM_INSUFFICIENT_MEMORY,
|
||||||
UNKNOWN_ERROR,
|
UNKNOWN_ERROR,
|
||||||
} from '../../constants/error-messages';
|
} from '../../constants/error-messages';
|
||||||
import { DatasourceError } from '../../datasource/common';
|
import { ExternalHostError } from '../../types/error';
|
||||||
import handleError from './error';
|
import handleError from './error';
|
||||||
|
|
||||||
jest.mock('./error-config');
|
jest.mock('./error-config');
|
||||||
|
@ -48,7 +47,6 @@ describe('workers/repository/error', () => {
|
||||||
REPOSITORY_FORKED,
|
REPOSITORY_FORKED,
|
||||||
MANAGER_NO_PACKAGE_FILES,
|
MANAGER_NO_PACKAGE_FILES,
|
||||||
CONFIG_VALIDATION,
|
CONFIG_VALIDATION,
|
||||||
DATASOURCE_FAILURE,
|
|
||||||
REPOSITORY_ARCHIVED,
|
REPOSITORY_ARCHIVED,
|
||||||
REPOSITORY_MIRRORED,
|
REPOSITORY_MIRRORED,
|
||||||
REPOSITORY_RENAMED,
|
REPOSITORY_RENAMED,
|
||||||
|
@ -60,7 +58,6 @@ describe('workers/repository/error', () => {
|
||||||
MANAGER_LOCKFILE_ERROR,
|
MANAGER_LOCKFILE_ERROR,
|
||||||
SYSTEM_INSUFFICIENT_DISK_SPACE,
|
SYSTEM_INSUFFICIENT_DISK_SPACE,
|
||||||
SYSTEM_INSUFFICIENT_MEMORY,
|
SYSTEM_INSUFFICIENT_MEMORY,
|
||||||
PLATFORM_FAILURE,
|
|
||||||
REPOSITORY_NO_VULNERABILITY,
|
REPOSITORY_NO_VULNERABILITY,
|
||||||
REPOSITORY_CANNOT_FORK,
|
REPOSITORY_CANNOT_FORK,
|
||||||
PLATFORM_INTEGRATION_UNAUTHORIZED,
|
PLATFORM_INTEGRATION_UNAUTHORIZED,
|
||||||
|
@ -73,23 +70,26 @@ describe('workers/repository/error', () => {
|
||||||
expect(res).toEqual(err);
|
expect(res).toEqual(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it(`handles DatasourceError`, async () => {
|
it(`handles ExternalHostError`, async () => {
|
||||||
const res = await handleError(config, new DatasourceError(new Error()));
|
const res = await handleError(
|
||||||
expect(res).toEqual(DATASOURCE_FAILURE);
|
config,
|
||||||
|
new ExternalHostError(new Error(), 'some-host-type')
|
||||||
|
);
|
||||||
|
expect(res).toEqual(EXTERNAL_HOST_ERROR);
|
||||||
});
|
});
|
||||||
it('rewrites git 5xx error', async () => {
|
it('rewrites git 5xx error', async () => {
|
||||||
const gitError = new Error(
|
const gitError = new Error(
|
||||||
"fatal: unable to access 'https://**redacted**@gitlab.com/learnox/learnox.git/': The requested URL returned error: 500\n"
|
"fatal: unable to access 'https://**redacted**@gitlab.com/learnox/learnox.git/': The requested URL returned error: 500\n"
|
||||||
);
|
);
|
||||||
const res = await handleError(config, gitError);
|
const res = await handleError(config, gitError);
|
||||||
expect(res).toEqual(PLATFORM_FAILURE);
|
expect(res).toEqual(EXTERNAL_HOST_ERROR);
|
||||||
});
|
});
|
||||||
it('rewrites git remote error', async () => {
|
it('rewrites git remote error', async () => {
|
||||||
const gitError = new Error(
|
const gitError = new Error(
|
||||||
'fatal: remote error: access denied or repository not exported: /b/nw/bd/27/47/159945428/108610112.git\n'
|
'fatal: remote error: access denied or repository not exported: /b/nw/bd/27/47/159945428/108610112.git\n'
|
||||||
);
|
);
|
||||||
const res = await handleError(config, gitError);
|
const res = await handleError(config, gitError);
|
||||||
expect(res).toEqual(PLATFORM_FAILURE);
|
expect(res).toEqual(EXTERNAL_HOST_ERROR);
|
||||||
});
|
});
|
||||||
it('handles unknown error', async () => {
|
it('handles unknown error', async () => {
|
||||||
const res = await handleError(config, new Error('abcdefg'));
|
const res = await handleError(config, new Error('abcdefg'));
|
||||||
|
|
|
@ -2,12 +2,11 @@ import { RenovateConfig } from '../../config';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CONFIG_VALIDATION,
|
CONFIG_VALIDATION,
|
||||||
DATASOURCE_FAILURE,
|
EXTERNAL_HOST_ERROR,
|
||||||
MANAGER_LOCKFILE_ERROR,
|
MANAGER_LOCKFILE_ERROR,
|
||||||
MANAGER_NO_PACKAGE_FILES,
|
MANAGER_NO_PACKAGE_FILES,
|
||||||
PLATFORM_AUTHENTICATION_ERROR,
|
PLATFORM_AUTHENTICATION_ERROR,
|
||||||
PLATFORM_BAD_CREDENTIALS,
|
PLATFORM_BAD_CREDENTIALS,
|
||||||
PLATFORM_FAILURE,
|
|
||||||
PLATFORM_INTEGRATION_UNAUTHORIZED,
|
PLATFORM_INTEGRATION_UNAUTHORIZED,
|
||||||
PLATFORM_RATE_LIMIT_EXCEEDED,
|
PLATFORM_RATE_LIMIT_EXCEEDED,
|
||||||
REPOSITORY_ACCESS_FORBIDDEN,
|
REPOSITORY_ACCESS_FORBIDDEN,
|
||||||
|
@ -28,8 +27,8 @@ import {
|
||||||
SYSTEM_INSUFFICIENT_MEMORY,
|
SYSTEM_INSUFFICIENT_MEMORY,
|
||||||
UNKNOWN_ERROR,
|
UNKNOWN_ERROR,
|
||||||
} from '../../constants/error-messages';
|
} from '../../constants/error-messages';
|
||||||
import { DatasourceError } from '../../datasource/common';
|
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
|
import { ExternalHostError } from '../../types/error';
|
||||||
import { raiseConfigWarningIssue } from './error-config';
|
import { raiseConfigWarningIssue } from './error-config';
|
||||||
|
|
||||||
export default async function handleError(
|
export default async function handleError(
|
||||||
|
@ -107,22 +106,12 @@ export default async function handleError(
|
||||||
await raiseConfigWarningIssue(config, err);
|
await raiseConfigWarningIssue(config, err);
|
||||||
return err.message;
|
return err.message;
|
||||||
}
|
}
|
||||||
if (err instanceof DatasourceError) {
|
if (err instanceof ExternalHostError) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
{ datasource: err.datasource, lookupName: err.lookupName, err: err.err },
|
{ hostType: err.hostType, lookupName: err.lookupName, err: err.err },
|
||||||
'Datasource failure'
|
'Host error'
|
||||||
);
|
);
|
||||||
logger.info('Registry error - skipping');
|
logger.info('External host error causing abort - skipping');
|
||||||
delete config.branchList; // eslint-disable-line no-param-reassign
|
|
||||||
return err.message;
|
|
||||||
}
|
|
||||||
if (err.message === DATASOURCE_FAILURE) {
|
|
||||||
logger.info({ err }, 'Registry error - skipping');
|
|
||||||
delete config.branchList; // eslint-disable-line no-param-reassign
|
|
||||||
return err.message;
|
|
||||||
}
|
|
||||||
if (err.message === PLATFORM_FAILURE) {
|
|
||||||
logger.info('Platform error - skipping');
|
|
||||||
delete config.branchList; // eslint-disable-line no-param-reassign
|
delete config.branchList; // eslint-disable-line no-param-reassign
|
||||||
return err.message;
|
return err.message;
|
||||||
}
|
}
|
||||||
|
@ -174,7 +163,7 @@ export default async function handleError(
|
||||||
logger.warn({ err }, 'Git error - aborting');
|
logger.warn({ err }, 'Git error - aborting');
|
||||||
delete config.branchList; // eslint-disable-line no-param-reassign
|
delete config.branchList; // eslint-disable-line no-param-reassign
|
||||||
// rewrite this error
|
// rewrite this error
|
||||||
return PLATFORM_FAILURE;
|
return EXTERNAL_HOST_ERROR;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
err.message.includes('The remote end hung up unexpectedly') ||
|
err.message.includes('The remote end hung up unexpectedly') ||
|
||||||
|
@ -183,7 +172,7 @@ export default async function handleError(
|
||||||
logger.warn({ err }, 'Git error - aborting');
|
logger.warn({ err }, 'Git error - aborting');
|
||||||
delete config.branchList; // eslint-disable-line no-param-reassign
|
delete config.branchList; // eslint-disable-line no-param-reassign
|
||||||
// rewrite this error
|
// rewrite this error
|
||||||
return PLATFORM_FAILURE;
|
return EXTERNAL_HOST_ERROR;
|
||||||
}
|
}
|
||||||
// Swallow this error so that other repositories can be processed
|
// Swallow this error so that other repositories can be processed
|
||||||
logger.error({ err }, `Repository has unknown error`);
|
logger.error({ err }, `Repository has unknown error`);
|
||||||
|
|
|
@ -7,13 +7,11 @@ import { configFileNames } from '../../../config/app-strings';
|
||||||
import { decryptConfig } from '../../../config/decrypt';
|
import { decryptConfig } from '../../../config/decrypt';
|
||||||
import { migrateAndValidate } from '../../../config/migrate-validate';
|
import { migrateAndValidate } from '../../../config/migrate-validate';
|
||||||
import * as presets from '../../../config/presets';
|
import * as presets from '../../../config/presets';
|
||||||
import {
|
import { CONFIG_VALIDATION } from '../../../constants/error-messages';
|
||||||
CONFIG_VALIDATION,
|
|
||||||
PLATFORM_FAILURE,
|
|
||||||
} from '../../../constants/error-messages';
|
|
||||||
import * as npmApi from '../../../datasource/npm';
|
import * as npmApi from '../../../datasource/npm';
|
||||||
import { logger } from '../../../logger';
|
import { logger } from '../../../logger';
|
||||||
import { platform } from '../../../platform';
|
import { platform } from '../../../platform';
|
||||||
|
import { ExternalHostError } from '../../../types/error';
|
||||||
import { readLocalFile } from '../../../util/fs';
|
import { readLocalFile } from '../../../util/fs';
|
||||||
import * as hostRules from '../../../util/host-rules';
|
import * as hostRules from '../../../util/host-rules';
|
||||||
import { flattenPackageRules } from './flatten';
|
import { flattenPackageRules } from './flatten';
|
||||||
|
@ -59,7 +57,10 @@ export async function mergeRenovateConfig(
|
||||||
// istanbul ignore if
|
// istanbul ignore if
|
||||||
if (renovateConfig === null) {
|
if (renovateConfig === null) {
|
||||||
logger.warn('Fetching renovate config returns null');
|
logger.warn('Fetching renovate config returns null');
|
||||||
throw new Error(PLATFORM_FAILURE);
|
throw new ExternalHostError(
|
||||||
|
Error('Fetching renovate config returns null'),
|
||||||
|
config.platform
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// istanbul ignore if
|
// istanbul ignore if
|
||||||
if (!renovateConfig.length) {
|
if (!renovateConfig.length) {
|
||||||
|
|
Loading…
Reference in a new issue