diff --git a/core/base-service/base-graphql.js b/core/base-service/base-graphql.js index 694a2f2720..a81bac29f9 100644 --- a/core/base-service/base-graphql.js +++ b/core/base-service/base-graphql.js @@ -44,6 +44,12 @@ class BaseGraphqlService extends BaseService { * and custom error messages e.g: `{ 404: 'package not found' }`. * This can be used to extend or override the * [default](https://github.com/badges/shields/blob/master/core/base-service/check-error-response.js#L5) + * @param {object} [attrs.systemErrors={}] Key-value map of got network exception codes + * and an object of params to pass when we construct an Inaccessible exception object + * e.g: `{ ECONNRESET: { prettyMessage: 'connection reset' } }`. + * See {@link https://github.com/sindresorhus/got/blob/main/documentation/7-retry.md#errorcodes got error codes} + * for allowed keys + * and {@link module:core/base-service/errors~RuntimeErrorProps} for allowed values * @param {Function} [attrs.transformJson=data => data] Function which takes the raw json and transforms it before * further procesing. In case of multiple query in a single graphql call and few of them * throw error, partial data might be used ignoring the error. @@ -62,6 +68,7 @@ class BaseGraphqlService extends BaseService { variables = {}, options = {}, httpErrorMessages = {}, + systemErrors = {}, transformJson = data => data, transformErrors = defaultTransformErrors, }) { @@ -74,7 +81,8 @@ class BaseGraphqlService extends BaseService { const { buffer } = await this._request({ url, options: mergedOptions, - errorMessages: httpErrorMessages, + httpErrors: httpErrorMessages, + systemErrors, }) const json = transformJson(this._parseJson(buffer)) if (json.errors) { diff --git a/core/base-service/base-json.js b/core/base-service/base-json.js index ebabf1a416..fe42783bd3 100644 --- a/core/base-service/base-json.js +++ b/core/base-service/base-json.js @@ -30,14 +30,26 @@ class BaseJsonService extends BaseService { * @param {string} attrs.url URL to request * @param {object} [attrs.options={}] Options to pass to got. See * [documentation](https://github.com/sindresorhus/got/blob/main/documentation/2-options.md) - * @param {object} [attrs.errorMessages={}] Key-value map of status codes + * @param {object} [attrs.httpErrors={}] Key-value map of status codes * and custom error messages e.g: `{ 404: 'package not found' }`. * This can be used to extend or override the * [default](https://github.com/badges/shields/blob/master/core/base-service/check-error-response.js#L5) + * @param {object} [attrs.systemErrors={}] Key-value map of got network exception codes + * and an object of params to pass when we construct an Inaccessible exception object + * e.g: `{ ECONNRESET: { prettyMessage: 'connection reset' } }`. + * See {@link https://github.com/sindresorhus/got/blob/main/documentation/7-retry.md#errorcodes got error codes} + * for allowed keys + * and {@link module:core/base-service/errors~RuntimeErrorProps} for allowed values * @returns {object} Parsed response * @see https://github.com/sindresorhus/got/blob/main/documentation/2-options.md */ - async _requestJson({ schema, url, options = {}, errorMessages = {} }) { + async _requestJson({ + schema, + url, + options = {}, + httpErrors = {}, + systemErrors = {}, + }) { const mergedOptions = { ...{ headers: { Accept: 'application/json' } }, ...options, @@ -45,7 +57,8 @@ class BaseJsonService extends BaseService { const { buffer } = await this._request({ url, options: mergedOptions, - errorMessages, + httpErrors, + systemErrors, }) const json = this._parseJson(buffer) return this.constructor._validate(json, schema) diff --git a/core/base-service/base-svg-scraping.js b/core/base-service/base-svg-scraping.js index a1cf981857..95bc3be8ac 100644 --- a/core/base-service/base-svg-scraping.js +++ b/core/base-service/base-svg-scraping.js @@ -53,10 +53,16 @@ class BaseSvgScrapingService extends BaseService { * @param {string} attrs.url URL to request * @param {object} [attrs.options={}] Options to pass to got. See * [documentation](https://github.com/sindresorhus/got/blob/main/documentation/2-options.md) - * @param {object} [attrs.errorMessages={}] Key-value map of status codes + * @param {object} [attrs.httpErrors={}] Key-value map of status codes * and custom error messages e.g: `{ 404: 'package not found' }`. * This can be used to extend or override the * [default](https://github.com/badges/shields/blob/master/core/base-service/check-error-response.js#L5) + * @param {object} [attrs.systemErrors={}] Key-value map of got network exception codes + * and an object of params to pass when we construct an Inaccessible exception object + * e.g: `{ ECONNRESET: { prettyMessage: 'connection reset' } }`. + * See {@link https://github.com/sindresorhus/got/blob/main/documentation/7-retry.md#errorcodes got error codes} + * for allowed keys + * and {@link module:core/base-service/errors~RuntimeErrorProps} for allowed values * @returns {object} Parsed response * @see https://github.com/sindresorhus/got/blob/main/documentation/2-options.md */ @@ -65,7 +71,8 @@ class BaseSvgScrapingService extends BaseService { valueMatcher, url, options = {}, - errorMessages = {}, + httpErrors = {}, + systemErrors = {}, }) { const logTrace = (...args) => trace.logTrace('fetch', ...args) const mergedOptions = { @@ -75,7 +82,8 @@ class BaseSvgScrapingService extends BaseService { const { buffer } = await this._request({ url, options: mergedOptions, - errorMessages, + httpErrors, + systemErrors, }) logTrace(emojic.dart, 'Response SVG', buffer) const data = { diff --git a/core/base-service/base-xml.js b/core/base-service/base-xml.js index d758781c39..7395c45ea6 100644 --- a/core/base-service/base-xml.js +++ b/core/base-service/base-xml.js @@ -24,10 +24,16 @@ class BaseXmlService extends BaseService { * @param {string} attrs.url URL to request * @param {object} [attrs.options={}] Options to pass to got. See * [documentation](https://github.com/sindresorhus/got/blob/main/documentation/2-options.md) - * @param {object} [attrs.errorMessages={}] Key-value map of status codes + * @param {object} [attrs.httpErrors={}] Key-value map of status codes * and custom error messages e.g: `{ 404: 'package not found' }`. * This can be used to extend or override the * [default](https://github.com/badges/shields/blob/master/core/base-service/check-error-response.js#L5) + * @param {object} [attrs.systemErrors={}] Key-value map of got network exception codes + * and an object of params to pass when we construct an Inaccessible exception object + * e.g: `{ ECONNRESET: { prettyMessage: 'connection reset' } }`. + * See {@link https://github.com/sindresorhus/got/blob/main/documentation/7-retry.md#errorcodes got error codes} + * for allowed keys + * and {@link module:core/base-service/errors~RuntimeErrorProps} for allowed values * @param {object} [attrs.parserOptions={}] Options to pass to fast-xml-parser. See * [documentation](https://github.com/NaturalIntelligence/fast-xml-parser#xml-to-json) * @returns {object} Parsed response @@ -38,7 +44,8 @@ class BaseXmlService extends BaseService { schema, url, options = {}, - errorMessages = {}, + httpErrors = {}, + systemErrors = {}, parserOptions = {}, }) { const logTrace = (...args) => trace.logTrace('fetch', ...args) @@ -49,7 +56,8 @@ class BaseXmlService extends BaseService { const { buffer } = await this._request({ url, options: mergedOptions, - errorMessages, + httpErrors, + systemErrors, }) const validateResult = XMLValidator.validate(buffer) if (validateResult !== true) { diff --git a/core/base-service/base-yaml.js b/core/base-service/base-yaml.js index 85e08f2d25..bae76068f2 100644 --- a/core/base-service/base-yaml.js +++ b/core/base-service/base-yaml.js @@ -23,10 +23,16 @@ class BaseYamlService extends BaseService { * @param {string} attrs.url URL to request * @param {object} [attrs.options={}] Options to pass to got. See * [documentation](https://github.com/sindresorhus/got/blob/main/documentation/2-options.md) - * @param {object} [attrs.errorMessages={}] Key-value map of status codes + * @param {object} [attrs.httpErrors={}] Key-value map of status codes * and custom error messages e.g: `{ 404: 'package not found' }`. * This can be used to extend or override the * [default](https://github.com/badges/shields/blob/master/core/base-service/check-error-response.js#L5) + * @param {object} [attrs.systemErrors={}] Key-value map of got network exception codes + * and an object of params to pass when we construct an Inaccessible exception object + * e.g: `{ ECONNRESET: { prettyMessage: 'connection reset' } }`. + * See {@link https://github.com/sindresorhus/got/blob/main/documentation/7-retry.md#errorcodes got error codes} + * for allowed keys + * and {@link module:core/base-service/errors~RuntimeErrorProps} for allowed values * @param {object} [attrs.encoding='utf8'] Character encoding * @returns {object} Parsed response * @see https://github.com/sindresorhus/got/blob/main/documentation/2-options.md @@ -35,7 +41,8 @@ class BaseYamlService extends BaseService { schema, url, options = {}, - errorMessages = {}, + httpErrors = {}, + systemErrors = {}, encoding = 'utf8', }) { const logTrace = (...args) => trace.logTrace('fetch', ...args) @@ -51,7 +58,8 @@ class BaseYamlService extends BaseService { const { buffer } = await this._request({ url, options: mergedOptions, - errorMessages, + httpErrors, + systemErrors, }) let parsed try { diff --git a/core/base-service/base.js b/core/base-service/base.js index f60470fa3b..cf077c562f 100644 --- a/core/base-service/base.js +++ b/core/base-service/base.js @@ -226,7 +226,7 @@ class BaseService { this._metricHelper = metricHelper } - async _request({ url, options = {}, errorMessages = {} }) { + async _request({ url, options = {}, httpErrors = {}, systemErrors = {} }) { const logTrace = (...args) => trace.logTrace('fetch', ...args) let logUrl = url const logOptions = Object.assign({}, options) @@ -246,10 +246,14 @@ class BaseService { 'Request', `${logUrl}\n${JSON.stringify(logOptions, null, 2)}` ) - const { res, buffer } = await this._requestFetcher(url, options) + const { res, buffer } = await this._requestFetcher( + url, + options, + systemErrors + ) await this._meterResponse(res, buffer) logTrace(emojic.dart, 'Response status code', res.statusCode) - return checkErrorResponse(errorMessages)({ buffer, res }) + return checkErrorResponse(httpErrors)({ buffer, res }) } static enabledMetrics = [] @@ -328,11 +332,15 @@ class BaseService { error instanceof Deprecated ) { trace.logTrace('outbound', emojic.noGoodWoman, 'Handled error', error) - return { + const serviceData = { isError: true, message: error.prettyMessage, color: 'lightgray', } + if (error.cacheSeconds !== undefined) { + serviceData.cacheSeconds = error.cacheSeconds + } + return serviceData } else if (this._handleInternalErrors) { if ( !trace.logTrace( diff --git a/core/base-service/cache-headers.js b/core/base-service/cache-headers.js index 14a707efae..2bd02e2f16 100644 --- a/core/base-service/cache-headers.js +++ b/core/base-service/cache-headers.js @@ -39,6 +39,7 @@ function coalesceCacheLength({ assert(defaultCacheLengthSeconds !== undefined) const cacheLength = coalesce( + serviceOverrideCacheLengthSeconds, serviceDefaultCacheLengthSeconds, defaultCacheLengthSeconds ) @@ -46,7 +47,6 @@ function coalesceCacheLength({ // Overrides can apply _more_ caching, but not less. Query param overriding // can request more overriding than service override, but not less. const candidateOverrides = [ - serviceOverrideCacheLengthSeconds, overrideCacheLengthFromQueryParams(queryParams), ].filter(x => x !== undefined) diff --git a/core/base-service/cache-headers.spec.js b/core/base-service/cache-headers.spec.js index ebfc53f815..fcf82ee749 100644 --- a/core/base-service/cache-headers.spec.js +++ b/core/base-service/cache-headers.spec.js @@ -74,12 +74,12 @@ describe('Cache header functions', function () { serviceDefaultCacheLengthSeconds: 900, serviceOverrideCacheLengthSeconds: 400, queryParams: {}, - }).expect(900) + }).expect(400) given({ cacheHeaderConfig, serviceOverrideCacheLengthSeconds: 400, queryParams: {}, - }).expect(777) + }).expect(400) given({ cacheHeaderConfig, serviceOverrideCacheLengthSeconds: 900, diff --git a/core/base-service/check-error-response.js b/core/base-service/check-error-response.js index 93120d725a..cda53fa7e9 100644 --- a/core/base-service/check-error-response.js +++ b/core/base-service/check-error-response.js @@ -5,19 +5,19 @@ const defaultErrorMessages = { 429: 'rate limited by upstream service', } -export default function checkErrorResponse(errorMessages = {}) { +export default function checkErrorResponse(httpErrors = {}) { return async function ({ buffer, res }) { let error - errorMessages = { ...defaultErrorMessages, ...errorMessages } + httpErrors = { ...defaultErrorMessages, ...httpErrors } if (res.statusCode === 404) { - error = new NotFound({ prettyMessage: errorMessages[404] }) + error = new NotFound({ prettyMessage: httpErrors[404] }) } else if (res.statusCode !== 200) { const underlying = Error( `Got status code ${res.statusCode} (expected 200)` ) const props = { underlyingError: underlying } - if (errorMessages[res.statusCode] !== undefined) { - props.prettyMessage = errorMessages[res.statusCode] + if (httpErrors[res.statusCode] !== undefined) { + props.prettyMessage = httpErrors[res.statusCode] } if (res.statusCode >= 500) { error = new Inaccessible(props) diff --git a/core/base-service/errors.js b/core/base-service/errors.js index a1c897ff6d..ce90f199d2 100644 --- a/core/base-service/errors.js +++ b/core/base-service/errors.js @@ -42,6 +42,7 @@ class ShieldsRuntimeError extends Error { if (props.underlyingError) { this.stack = props.underlyingError.stack } + this.cacheSeconds = props.cacheSeconds } } @@ -206,6 +207,9 @@ class Deprecated extends ShieldsRuntimeError { * @property {string} prettyMessage User-facing error message to override the * value of `defaultPrettyMessage()`. This is the text that will appear on the * badge when we catch and render the exception (Optional) + * @property {number} cacheSeconds Length of time to cache this error response + * for. Defaults to the cacheLength of the service class throwing the error + * (Optional) */ export { diff --git a/core/base-service/got.js b/core/base-service/got.js index 773aa3b57f..793901e7ea 100644 --- a/core/base-service/got.js +++ b/core/base-service/got.js @@ -7,7 +7,7 @@ import { const userAgent = getUserAgent() -async function sendRequest(gotWrapper, url, options) { +async function sendRequest(gotWrapper, url, options = {}, systemErrors = {}) { const gotOptions = Object.assign({}, options) gotOptions.throwHttpErrors = false gotOptions.retry = { limit: 0 } @@ -22,6 +22,12 @@ async function sendRequest(gotWrapper, url, options) { underlyingError: new Error('Maximum response size exceeded'), }) } + if (err.code in systemErrors) { + throw new Inaccessible({ + ...systemErrors[err.code], + underlyingError: err, + }) + } throw new Inaccessible({ underlyingError: err }) } } diff --git a/core/base-service/got.spec.js b/core/base-service/got.spec.js index 004ee667a1..37b201f0f5 100644 --- a/core/base-service/got.spec.js +++ b/core/base-service/got.spec.js @@ -45,6 +45,36 @@ describe('got wrapper', function () { ) }) + it('should throw a custom error if provided', async function () { + const sendRequest = _fetchFactory(1024) + return ( + expect( + sendRequest( + 'https://www.google.com/foo/bar', + { timeout: { request: 1 } }, + { + ETIMEDOUT: { + prettyMessage: 'Oh no! A terrible thing has happened', + cacheSeconds: 10, + }, + } + ) + ) + .to.be.rejectedWith( + Inaccessible, + "Inaccessible: Timeout awaiting 'request' for 1ms" + ) + // eslint-disable-next-line promise/prefer-await-to-then + .then(error => { + expect(error).to.have.property( + 'prettyMessage', + 'Oh no! A terrible thing has happened' + ) + expect(error).to.have.property('cacheSeconds', 10) + }) + ) + }) + it('should pass a custom user agent header', async function () { nock('https://www.google.com', { reqheaders: { diff --git a/core/base-service/legacy-request-handler.js b/core/base-service/legacy-request-handler.js index 2e5b7e92b9..9ef3d4efeb 100644 --- a/core/base-service/legacy-request-handler.js +++ b/core/base-service/legacy-request-handler.js @@ -73,11 +73,9 @@ function handleRequest(cacheHeaderConfig, handlerOptions) { // `defaultCacheLengthSeconds` can be overridden by // `serviceDefaultCacheLengthSeconds` (either by category or on a badge- // by-badge basis). Then in turn that can be overridden by - // `serviceOverrideCacheLengthSeconds` (which we expect to be used only in - // the dynamic badge) but only if `serviceOverrideCacheLengthSeconds` is - // longer than `serviceDefaultCacheLengthSeconds` and then the `cacheSeconds` - // query param can also override both of those but again only if `cacheSeconds` - // is longer. + // `serviceOverrideCacheLengthSeconds`. + // Then the `cacheSeconds` query param can also override both of those + // but only if `cacheSeconds` is longer. // // When the legacy services have been rewritten, all the code in here // will go away, which should achieve this goal in a simpler way. diff --git a/core/base-service/legacy-request-handler.spec.js b/core/base-service/legacy-request-handler.spec.js index 2265f18e69..9293e42eca 100644 --- a/core/base-service/legacy-request-handler.spec.js +++ b/core/base-service/legacy-request-handler.spec.js @@ -148,7 +148,7 @@ describe('The request handler', function () { expect(headers['cache-control']).to.equal('max-age=900, s-maxage=900') }) - it('should let live service data override the default cache headers with longer value', async function () { + it('should allow serviceData to override the default cache headers with longer value', async function () { camp.route( /^\/testing\/([^/]+)\.(svg|png|gif|jpg|json)$/, handleRequest( @@ -168,7 +168,7 @@ describe('The request handler', function () { expect(headers['cache-control']).to.equal('max-age=400, s-maxage=400') }) - it('should not let live service data override the default cache headers with shorter value', async function () { + it('should allow serviceData to override the default cache headers with shorter value', async function () { camp.route( /^\/testing\/([^/]+)\.(svg|png|gif|jpg|json)$/, handleRequest( @@ -185,7 +185,7 @@ describe('The request handler', function () { ) const { headers } = await got(`${baseUrl}/testing/123.json`) - expect(headers['cache-control']).to.equal('max-age=300, s-maxage=300') + expect(headers['cache-control']).to.equal('max-age=200, s-maxage=200') }) it('should set the expires header to current time + cacheSeconds', async function () { diff --git a/doc/TUTORIAL.md b/doc/TUTORIAL.md index 06441df876..f649f197ce 100644 --- a/doc/TUTORIAL.md +++ b/doc/TUTORIAL.md @@ -229,14 +229,14 @@ Description of the code: - `_requestJson()` automatically adds an Accept header, checks the status code, parses the response as JSON, and returns the parsed response. - `_requestJson()` uses [got](https://github.com/sindresorhus/got) to perform the HTTP request. Options can be passed to got, including method, query string, and headers. If headers are provided they will override the ones automatically set by `_requestJson()`. There is no need to specify json, as the JSON parsing is handled by `_requestJson()`. See the `got` docs for [supported options](https://github.com/sindresorhus/got/blob/main/documentation/2-options.md). - - Error messages corresponding to each status code can be returned by passing a dictionary of status codes -> messages in `errorMessages`. + - Error messages corresponding to each status code can be returned by passing a dictionary of status codes -> messages in `httpErrors`. - A more complex call to `_requestJson()` might look like this: ```js return this._requestJson({ schema: mySchema, url, options: { searchParams: { branch: 'master' } }, - errorMessages: { + httpErrors: { 401: 'private application not supported', 404: 'application not found', }, diff --git a/doc/service-tests.md b/doc/service-tests.md index 2242920f68..45f5cd8163 100644 --- a/doc/service-tests.md +++ b/doc/service-tests.md @@ -152,7 +152,7 @@ npm run test:services -- --only="wercker" --fgrep="Build status (with branch)" Having covered the typical and custom cases, we'll move on to errors. We should include a test for the 'not found' response and also tests for any other custom error handling. The Wercker integration defines a custom error condition for 401 as well as a custom 404 message: ```js -errorMessages: { +httpErrors: { 401: 'private application not supported', 404: 'application not found', } diff --git a/services/appveyor/appveyor-base.js b/services/appveyor/appveyor-base.js index 923b718466..9903beae5f 100644 --- a/services/appveyor/appveyor-base.js +++ b/services/appveyor/appveyor-base.js @@ -29,7 +29,7 @@ export default class AppVeyorBase extends BaseJsonService { return this._requestJson({ schema, url, - errorMessages: { 404: 'project not found or access denied' }, + httpErrors: { 404: 'project not found or access denied' }, }) } diff --git a/services/azure-devops/azure-devops-base.js b/services/azure-devops/azure-devops-base.js index 6b01bea846..85331836d4 100644 --- a/services/azure-devops/azure-devops-base.js +++ b/services/azure-devops/azure-devops-base.js @@ -19,13 +19,13 @@ export default class AzureDevOpsBase extends BaseJsonService { defaultToEmptyStringForUser: true, } - async fetch({ url, options, schema, errorMessages }) { + async fetch({ url, options, schema, httpErrors }) { return this._requestJson( this.authHelper.withBasicAuth({ schema, url, options, - errorMessages, + httpErrors, }) ) } @@ -35,7 +35,7 @@ export default class AzureDevOpsBase extends BaseJsonService { project, definitionId, branch, - errorMessages + httpErrors ) { // Microsoft documentation: https://docs.microsoft.com/en-us/rest/api/azure/devops/build/builds/list?view=azure-devops-rest-5.0 const url = `https://dev.azure.com/${organization}/${project}/_apis/build/builds` @@ -56,7 +56,7 @@ export default class AzureDevOpsBase extends BaseJsonService { url, options, schema: latestBuildSchema, - errorMessages, + httpErrors, }) if (json.count !== 1) { diff --git a/services/azure-devops/azure-devops-build.service.js b/services/azure-devops/azure-devops-build.service.js index a4c2bc93b7..98403df403 100644 --- a/services/azure-devops/azure-devops-build.service.js +++ b/services/azure-devops/azure-devops-build.service.js @@ -109,7 +109,7 @@ export default class AzureDevOpsBuild extends BaseSvgScrapingService { stageName: stage, jobName: job, }, - errorMessages: { + httpErrors: { 404: 'user or project not found', }, }) diff --git a/services/azure-devops/azure-devops-coverage.service.js b/services/azure-devops/azure-devops-coverage.service.js index eb5b7eeb79..6ab0ad9fe0 100644 --- a/services/azure-devops/azure-devops-coverage.service.js +++ b/services/azure-devops/azure-devops-coverage.service.js @@ -88,7 +88,7 @@ export default class AzureDevOpsCoverage extends AzureDevOpsBase { } async handle({ organization, project, definitionId, branch }) { - const errorMessages = { + const httpErrors = { 404: 'build pipeline or coverage not found', } const buildId = await this.getLatestCompletedBuildId( @@ -96,7 +96,7 @@ export default class AzureDevOpsCoverage extends AzureDevOpsBase { project, definitionId, branch, - errorMessages + httpErrors ) // Microsoft documentation: https://docs.microsoft.com/en-us/rest/api/azure/devops/test/code%20coverage/get%20build%20code%20coverage?view=azure-devops-rest-5.0 const url = `https://dev.azure.com/${organization}/${project}/_apis/test/codecoverage` @@ -110,7 +110,7 @@ export default class AzureDevOpsCoverage extends AzureDevOpsBase { url, options, schema: buildCodeCoverageSchema, - errorMessages, + httpErrors, }) let covered = 0 diff --git a/services/azure-devops/azure-devops-helpers.js b/services/azure-devops/azure-devops-helpers.js index e57f8c8347..a2a0c89694 100644 --- a/services/azure-devops/azure-devops-helpers.js +++ b/services/azure-devops/azure-devops-helpers.js @@ -15,16 +15,13 @@ const schema = Joi.object({ .required(), }).required() -async function fetch( - serviceInstance, - { url, searchParams = {}, errorMessages } -) { +async function fetch(serviceInstance, { url, searchParams = {}, httpErrors }) { // Microsoft documentation: https://docs.microsoft.com/en-us/rest/api/vsts/build/status/get const { message: status } = await serviceInstance._requestSvg({ schema, url, options: { searchParams }, - errorMessages, + httpErrors, }) return { status } } diff --git a/services/azure-devops/azure-devops-release.service.js b/services/azure-devops/azure-devops-release.service.js index 96393ad4b0..288f62435d 100644 --- a/services/azure-devops/azure-devops-release.service.js +++ b/services/azure-devops/azure-devops-release.service.js @@ -49,7 +49,7 @@ export default class AzureDevOpsRelease extends BaseSvgScrapingService { // Microsoft documentation: ? const props = await fetch(this, { url: `https://vsrm.dev.azure.com/${organization}/_apis/public/Release/badge/${projectId}/${definitionId}/${environmentId}`, - errorMessages: { + httpErrors: { 400: 'project not found', 404: 'user or environment not found', 500: 'inaccessible or definition not found', diff --git a/services/azure-devops/azure-devops-tests.service.js b/services/azure-devops/azure-devops-tests.service.js index 8b10ebf431..e27b505f55 100644 --- a/services/azure-devops/azure-devops-tests.service.js +++ b/services/azure-devops/azure-devops-tests.service.js @@ -145,7 +145,7 @@ export default class AzureDevOpsTests extends AzureDevOpsBase { } async fetchTestResults({ organization, project, definitionId, branch }) { - const errorMessages = { + const httpErrors = { 404: 'build pipeline or test result summary not found', } const buildId = await this.getLatestCompletedBuildId( @@ -153,7 +153,7 @@ export default class AzureDevOpsTests extends AzureDevOpsBase { project, definitionId, branch, - errorMessages + httpErrors ) // https://dev.azure.com/azuredevops-powershell/azuredevops-powershell/_apis/test/ResultSummaryByBuild?buildId=20 @@ -163,7 +163,7 @@ export default class AzureDevOpsTests extends AzureDevOpsBase { searchParams: { buildId }, }, schema: buildTestResultSummarySchema, - errorMessages, + httpErrors, }) } diff --git a/services/bit/bit-components.service.js b/services/bit/bit-components.service.js index e223663903..15f27730d4 100644 --- a/services/bit/bit-components.service.js +++ b/services/bit/bit-components.service.js @@ -37,7 +37,7 @@ export default class BitComponents extends BaseJsonService { return this._requestJson({ url, schema: collectionSchema, - errorMessages: { + httpErrors: { 404: 'collection not found', }, }) diff --git a/services/bitbucket/bitbucket-issues.service.js b/services/bitbucket/bitbucket-issues.service.js index 38eafea3a3..2da5a629cd 100644 --- a/services/bitbucket/bitbucket-issues.service.js +++ b/services/bitbucket/bitbucket-issues.service.js @@ -46,7 +46,7 @@ function issueClassGenerator(raw) { options: { searchParams: { limit: 0, q: '(state = "new" OR state = "open")' }, }, - errorMessages: { 403: 'private repo' }, + httpErrors: { 403: 'private repo' }, }) } diff --git a/services/bitbucket/bitbucket-pipelines.service.js b/services/bitbucket/bitbucket-pipelines.service.js index 29d0277d4b..878a518a3b 100644 --- a/services/bitbucket/bitbucket-pipelines.service.js +++ b/services/bitbucket/bitbucket-pipelines.service.js @@ -63,7 +63,7 @@ class BitbucketPipelines extends BaseJsonService { 'target.ref_name': branch, }, }, - errorMessages: { 403: 'private repo' }, + httpErrors: { 403: 'private repo' }, }) } diff --git a/services/bitbucket/bitbucket-pull-request.service.js b/services/bitbucket/bitbucket-pull-request.service.js index b885109fb5..9606e82138 100644 --- a/services/bitbucket/bitbucket-pull-request.service.js +++ b/services/bitbucket/bitbucket-pull-request.service.js @@ -12,7 +12,7 @@ const queryParamSchema = Joi.object({ server: optionalUrl, }).required() -const errorMessages = { +const httpErrors = { 401: 'invalid credentials', 403: 'private repo', 404: 'not found', @@ -87,7 +87,7 @@ function pullRequestClassGenerator(raw) { url: `https://bitbucket.org/api/2.0/repositories/${user}/${repo}/pullrequests/`, schema, options: { searchParams: { state: 'OPEN', limit: 0 } }, - errorMessages, + httpErrors, }) ) } @@ -106,7 +106,7 @@ function pullRequestClassGenerator(raw) { withAttributes: false, }, }, - errorMessages, + httpErrors, }) ) } diff --git a/services/bitrise/bitrise.service.js b/services/bitrise/bitrise.service.js index cca2a78666..49e5f2fb90 100644 --- a/services/bitrise/bitrise.service.js +++ b/services/bitrise/bitrise.service.js @@ -55,7 +55,7 @@ export default class Bitrise extends BaseJsonService { )}/status.json`, options: { searchParams: { token, branch } }, schema, - errorMessages: { + httpErrors: { 403: 'app not found or invalid token', }, }) diff --git a/services/bower/bower-base.js b/services/bower/bower-base.js index 92fb2c1e26..2ead07514a 100644 --- a/services/bower/bower-base.js +++ b/services/bower/bower-base.js @@ -22,7 +22,7 @@ export default class BaseBowerService extends LibrariesIoBase { return this._requestJson({ schema, url: `/bower/${packageName}`, - errorMessages: { + httpErrors: { 404: 'package not found', }, }) diff --git a/services/bundlephobia/bundlephobia.service.js b/services/bundlephobia/bundlephobia.service.js index c3fed6cdd1..68ac512620 100644 --- a/services/bundlephobia/bundlephobia.service.js +++ b/services/bundlephobia/bundlephobia.service.js @@ -84,7 +84,7 @@ export default class Bundlephobia extends BaseJsonService { schema, url: 'https://bundlephobia.com/api/size', options, - errorMessages: { + httpErrors: { 404: 'package or version not found', }, }) diff --git a/services/cii-best-practices/cii-best-practices.service.js b/services/cii-best-practices/cii-best-practices.service.js index d7230334dd..2ee81cec50 100644 --- a/services/cii-best-practices/cii-best-practices.service.js +++ b/services/cii-best-practices/cii-best-practices.service.js @@ -115,7 +115,7 @@ export default class CIIBestPracticesService extends BaseJsonService { await this._requestJson({ schema, url: `https://bestpractices.coreinfrastructure.org/projects/${projectId}/badge.json`, - errorMessages: { + httpErrors: { 404: 'project not found', }, }) diff --git a/services/circleci/circleci.service.js b/services/circleci/circleci.service.js index 11dd943cd3..49ca87d5d0 100644 --- a/services/circleci/circleci.service.js +++ b/services/circleci/circleci.service.js @@ -57,7 +57,7 @@ class CircleCi extends BaseSvgScrapingService { // Note that the unusual 'circle-token' query param name is required. // https://circleci.com/docs/api/#get-authenticated options: { searchParams: { style: 'shield', 'circle-token': token } }, - errorMessages: { 404: 'project not found' }, + httpErrors: { 404: 'project not found' }, }) return this.constructor.render({ status: message }) } diff --git a/services/clearlydefined/clearlydefined-score.service.js b/services/clearlydefined/clearlydefined-score.service.js index f480581af6..d100df5bcc 100644 --- a/services/clearlydefined/clearlydefined-score.service.js +++ b/services/clearlydefined/clearlydefined-score.service.js @@ -53,7 +53,7 @@ export default class ClearlyDefinedService extends BaseJsonService { return this._requestJson({ schema, url: `https://api.clearlydefined.io/definitions/${type}/${provider}/${namespace}/${name}/${revision}`, - errorMessages: { + httpErrors: { 500: 'unknown type, provider, or upstream issue', }, }) diff --git a/services/codacy/codacy-coverage.service.js b/services/codacy/codacy-coverage.service.js index d57c1e80e3..7deae5d34d 100644 --- a/services/codacy/codacy-coverage.service.js +++ b/services/codacy/codacy-coverage.service.js @@ -53,7 +53,7 @@ export default class CodacyCoverage extends BaseSvgScrapingService { )}`, options: { searchParams: { branch } }, valueMatcher: /text-anchor="middle">([^<>]+)<\/text>/, - errorMessages: { + httpErrors: { 404: 'project not found', }, }) diff --git a/services/codacy/codacy-grade.service.js b/services/codacy/codacy-grade.service.js index aeee96579c..afb4ccabcc 100644 --- a/services/codacy/codacy-grade.service.js +++ b/services/codacy/codacy-grade.service.js @@ -51,7 +51,7 @@ export default class CodacyGrade extends BaseSvgScrapingService { projectId )}`, options: { searchParams: { branch } }, - errorMessages: { 404: 'project or branch not found' }, + httpErrors: { 404: 'project or branch not found' }, valueMatcher: /visibility="hidden">([^<>]+)<\/text>/, }) return this.constructor.render({ grade }) diff --git a/services/codecov/codecov.service.js b/services/codecov/codecov.service.js index d6ab261498..6c505854ba 100644 --- a/services/codecov/codecov.service.js +++ b/services/codecov/codecov.service.js @@ -117,7 +117,7 @@ export default class Codecov extends BaseSvgScrapingService { Authorization: `token ${token}`, }, }, - errorMessages: { + httpErrors: { 401: 'not authorized to access repository', 404: 'repository not found', }, @@ -153,7 +153,7 @@ export default class Codecov extends BaseSvgScrapingService { options: { searchParams: { token, flag }, }, - errorMessages: token ? { 400: 'invalid token pattern' } : {}, + httpErrors: token ? { 400: 'invalid token pattern' } : {}, }) } diff --git a/services/codefactor/codefactor-grade.service.js b/services/codefactor/codefactor-grade.service.js index 70528574be..0752654565 100644 --- a/services/codefactor/codefactor-grade.service.js +++ b/services/codefactor/codefactor-grade.service.js @@ -41,7 +41,7 @@ export default class CodeFactorGrade extends BaseSvgScrapingService { url: `https://codefactor.io/repository/${vcsType}/${user}/${repo}/badge/${ branch || '' }`, - errorMessages: { 404: 'repo or branch not found' }, + httpErrors: { 404: 'repo or branch not found' }, }) return this.constructor.render({ grade: message }) } diff --git a/services/coincap/coincap-base.js b/services/coincap/coincap-base.js index 7ad3dfb6c6..d602fb2529 100644 --- a/services/coincap/coincap-base.js +++ b/services/coincap/coincap-base.js @@ -12,7 +12,7 @@ export default class BaseCoincapService extends BaseJsonService { return this._requestJson({ schema, url: `https://api.coincap.io/v2/assets/${assetId}`, - errorMessages: { + httpErrors: { 404: 'asset not found', }, }) diff --git a/services/coveralls/coveralls.service.js b/services/coveralls/coveralls.service.js index 9f20c419be..1b2b412f35 100644 --- a/services/coveralls/coveralls.service.js +++ b/services/coveralls/coveralls.service.js @@ -66,7 +66,7 @@ export default class Coveralls extends BaseJsonService { schema, url, options, - errorMessages: { + httpErrors: { 404: 'repository not found', }, }) diff --git a/services/coverity/coverity-scan.service.js b/services/coverity/coverity-scan.service.js index 2c1e936236..7f6a74210b 100644 --- a/services/coverity/coverity-scan.service.js +++ b/services/coverity/coverity-scan.service.js @@ -48,7 +48,7 @@ export default class CoverityScan extends BaseJsonService { const json = await this._requestJson({ url, schema, - errorMessages: { + httpErrors: { // At the moment Coverity returns an HTTP 200 with an HTML page // displaying the text 404 when project is not found. 404: 'project not found', diff --git a/services/discord/discord.service.js b/services/discord/discord.service.js index 65837b9a35..5fe8944be1 100644 --- a/services/discord/discord.service.js +++ b/services/discord/discord.service.js @@ -63,7 +63,7 @@ export default class Discord extends BaseJsonService { { url, schema, - errorMessages: { + httpErrors: { 404: 'invalid server', 403: 'widget disabled', }, diff --git a/services/docker/docker-automated.service.js b/services/docker/docker-automated.service.js index ba28af2990..c5432f8134 100644 --- a/services/docker/docker-automated.service.js +++ b/services/docker/docker-automated.service.js @@ -40,7 +40,7 @@ export default class DockerAutomatedBuild extends BaseJsonService { url: `https://registry.hub.docker.com/v2/repositories/${getDockerHubUser( user )}/${repo}`, - errorMessages: { 404: 'repo not found' }, + httpErrors: { 404: 'repo not found' }, }) } diff --git a/services/docker/docker-cloud-common-fetch.js b/services/docker/docker-cloud-common-fetch.js index 51d763261e..bea59e66d3 100644 --- a/services/docker/docker-cloud-common-fetch.js +++ b/services/docker/docker-cloud-common-fetch.js @@ -16,7 +16,7 @@ async function fetchBuild(serviceInstance, { user, repo }) { schema: cloudBuildSchema, url: 'https://cloud.docker.com/api/build/v1/source', options: { searchParams: { image: `${user}/${repo}` } }, - errorMessages: { 404: 'repo not found' }, + httpErrors: { 404: 'repo not found' }, }) } diff --git a/services/docker/docker-pulls.service.js b/services/docker/docker-pulls.service.js index 4a31a16843..e1a8e8a129 100644 --- a/services/docker/docker-pulls.service.js +++ b/services/docker/docker-pulls.service.js @@ -38,7 +38,7 @@ export default class DockerPulls extends BaseJsonService { url: `https://hub.docker.com/v2/repositories/${getDockerHubUser( user )}/${repo}`, - errorMessages: { 404: 'repo not found' }, + httpErrors: { 404: 'repo not found' }, }) } diff --git a/services/docker/docker-size.service.js b/services/docker/docker-size.service.js index 4d4c5f6a6a..bef483105c 100644 --- a/services/docker/docker-size.service.js +++ b/services/docker/docker-size.service.js @@ -107,7 +107,7 @@ export default class DockerSize extends BaseJsonService { )}/${repo}/tags${ tag ? `/${tag}` : '?page_size=100&ordering=last_updated' }${page}`, - errorMessages: { 404: 'repository or tag not found' }, + httpErrors: { 404: 'repository or tag not found' }, }) } diff --git a/services/docker/docker-stars.service.js b/services/docker/docker-stars.service.js index f7e645aba1..49a43e5d61 100644 --- a/services/docker/docker-stars.service.js +++ b/services/docker/docker-stars.service.js @@ -41,7 +41,7 @@ export default class DockerStars extends BaseJsonService { url: `https://hub.docker.com/v2/repositories/${getDockerHubUser( user )}/${repo}/`, - errorMessages: { 404: 'repo not found' }, + httpErrors: { 404: 'repo not found' }, }) } diff --git a/services/docker/docker-version.service.js b/services/docker/docker-version.service.js index 594c8e9647..e61ff42a42 100644 --- a/services/docker/docker-version.service.js +++ b/services/docker/docker-version.service.js @@ -69,7 +69,7 @@ export default class DockerVersion extends BaseJsonService { url: `https://registry.hub.docker.com/v2/repositories/${getDockerHubUser( user )}/${repo}/tags?page_size=100&ordering=last_updated${page}`, - errorMessages: { 404: 'repository or tag not found' }, + httpErrors: { 404: 'repository or tag not found' }, }) } diff --git a/services/drone/drone-build.service.js b/services/drone/drone-build.service.js index 3951fd84da..74132b6046 100644 --- a/services/drone/drone-build.service.js +++ b/services/drone/drone-build.service.js @@ -75,7 +75,7 @@ export default class DroneBuild extends BaseJsonService { options: { searchParams: { ref: branch ? `refs/heads/${branch}` : undefined }, }, - errorMessages: { + httpErrors: { 401: 'repo not found or not authorized', }, }) diff --git a/services/dynamic-common.js b/services/dynamic-common.js index d82faaf811..04a68e78cd 100644 --- a/services/dynamic-common.js +++ b/services/dynamic-common.js @@ -14,7 +14,7 @@ import { InvalidResponse } from './index.js' * * @type {object} */ -const errorMessages = { +const httpErrors = { 404: 'resource not found', } @@ -93,7 +93,7 @@ function renderDynamicBadge({ } export { - errorMessages, + httpErrors, individualValueSchema, transformAndValidate, renderDynamicBadge, diff --git a/services/dynamic/dynamic-json.service.js b/services/dynamic/dynamic-json.service.js index 0dc3fa56a8..68ffd4f6dc 100644 --- a/services/dynamic/dynamic-json.service.js +++ b/services/dynamic/dynamic-json.service.js @@ -54,11 +54,11 @@ export default class DynamicJson extends jsonPath(BaseJsonService) { }, } - async fetch({ schema, url, errorMessages }) { + async fetch({ schema, url, httpErrors }) { return this._requestJson({ schema, url, - errorMessages, + httpErrors, }) } } diff --git a/services/dynamic/dynamic-xml.service.js b/services/dynamic/dynamic-xml.service.js index 3426af989b..fd4216c5a0 100644 --- a/services/dynamic/dynamic-xml.service.js +++ b/services/dynamic/dynamic-xml.service.js @@ -1,7 +1,7 @@ import { DOMParser } from '@xmldom/xmldom' import xpath from 'xpath' import { MetricNames } from '../../core/base-service/metric-helper.js' -import { renderDynamicBadge, errorMessages } from '../dynamic-common.js' +import { renderDynamicBadge, httpErrors } from '../dynamic-common.js' import { BaseService, InvalidResponse, InvalidParameter } from '../index.js' import { createRoute } from './dynamic-helpers.js' @@ -113,7 +113,7 @@ export default class DynamicXml extends BaseService { const { buffer } = await this._request({ url, options: { headers: { Accept: 'application/xml, text/xml' } }, - errorMessages, + httpErrors, }) const { values: value } = this.transform({ diff --git a/services/dynamic/dynamic-yaml.service.js b/services/dynamic/dynamic-yaml.service.js index 46f84dd8e0..c1a5ab29ce 100644 --- a/services/dynamic/dynamic-yaml.service.js +++ b/services/dynamic/dynamic-yaml.service.js @@ -54,11 +54,11 @@ export default class DynamicYaml extends jsonPath(BaseYamlService) { }, } - async fetch({ schema, url, errorMessages }) { + async fetch({ schema, url, httpErrors }) { return this._requestYaml({ schema, url, - errorMessages, + httpErrors, }) } } diff --git a/services/dynamic/json-path.js b/services/dynamic/json-path.js index ed242c944a..64c45d1578 100644 --- a/services/dynamic/json-path.js +++ b/services/dynamic/json-path.js @@ -4,7 +4,7 @@ import Joi from 'joi' import jp from 'jsonpath' -import { renderDynamicBadge, errorMessages } from '../dynamic-common.js' +import { renderDynamicBadge, httpErrors } from '../dynamic-common.js' import { InvalidParameter, InvalidResponse } from '../index.js' /** @@ -24,13 +24,13 @@ export default superclass => * @param {object} attrs Refer to individual attrs * @param {Joi} attrs.schema Joi schema to validate the response transformed to JSON * @param {string} attrs.url URL to request - * @param {object} [attrs.errorMessages={}] Key-value map of status codes + * @param {object} [attrs.httpErrors={}] Key-value map of status codes * and custom error messages e.g: `{ 404: 'package not found' }`. * This can be used to extend or override the * [default](https://github.com/badges/shields/blob/master/services/dynamic-common.js#L8) * @returns {object} Parsed response */ - async fetch({ schema, url, errorMessages }) { + async fetch({ schema, url, httpErrors }) { throw new Error( `fetch() function not implemented for ${this.constructor.name}` ) @@ -40,7 +40,7 @@ export default superclass => const data = await this.fetch({ schema: Joi.any(), url, - errorMessages, + httpErrors, }) // JSONPath only works on objects and arrays. diff --git a/services/eclipse-marketplace/eclipse-marketplace-base.js b/services/eclipse-marketplace/eclipse-marketplace-base.js index a4276731b9..2324219ef2 100644 --- a/services/eclipse-marketplace/eclipse-marketplace-base.js +++ b/services/eclipse-marketplace/eclipse-marketplace-base.js @@ -12,7 +12,7 @@ export default class EclipseMarketplaceBase extends BaseXmlService { return this._requestXml({ schema, url: `https://marketplace.eclipse.org/content/${name}/api/p`, - errorMessages: { 404: 'solution not found' }, + httpErrors: { 404: 'solution not found' }, }) } } diff --git a/services/ecologi/ecologi-carbon.service.js b/services/ecologi/ecologi-carbon.service.js index 4aac425d1e..01d878780f 100644 --- a/services/ecologi/ecologi-carbon.service.js +++ b/services/ecologi/ecologi-carbon.service.js @@ -30,7 +30,7 @@ export default class EcologiCarbonOffset extends BaseJsonService { return this._requestJson({ url, schema: apiSchema, - errorMessages: { + httpErrors: { 404: 'username not found', }, }) diff --git a/services/ecologi/ecologi-trees.service.js b/services/ecologi/ecologi-trees.service.js index 46d41b2f00..0d4225bb17 100644 --- a/services/ecologi/ecologi-trees.service.js +++ b/services/ecologi/ecologi-trees.service.js @@ -30,7 +30,7 @@ export default class EcologiTrees extends BaseJsonService { return this._requestJson({ url, schema: apiSchema, - errorMessages: { + httpErrors: { 404: 'username not found', }, }) diff --git a/services/elm-package/elm-package.service.js b/services/elm-package/elm-package.service.js index dd606d090c..cf608fd597 100644 --- a/services/elm-package/elm-package.service.js +++ b/services/elm-package/elm-package.service.js @@ -27,7 +27,7 @@ export default class ElmPackage extends BaseJsonService { const { version } = await this._requestJson({ schema, url, - errorMessages: { + httpErrors: { 404: 'package not found', }, }) diff --git a/services/endpoint-common.js b/services/endpoint-common.js index 5b5c998281..164762fd82 100644 --- a/services/endpoint-common.js +++ b/services/endpoint-common.js @@ -82,19 +82,19 @@ const anySchema = Joi.any() * @param {object} serviceInstance Instance of Endpoint class * @param {object} attrs Refer to individual attributes * @param {string} attrs.url Endpoint URL - * @param {object} attrs.errorMessages Object containing error messages for different error codes + * @param {object} attrs.httpErrors Object containing error messages for different error codes * @param {string} attrs.validationPrettyErrorMessage If provided then the error message is set to this value * @param {boolean} attrs.includeKeys If true then includes error details in error message * @returns {object} Data fetched from endpoint */ async function fetchEndpointData( serviceInstance, - { url, errorMessages, validationPrettyErrorMessage, includeKeys } + { url, httpErrors, validationPrettyErrorMessage, includeKeys } ) { const json = await serviceInstance._requestJson({ schema: anySchema, url, - errorMessages, + httpErrors, options: { decompress: true }, }) return validateEndpointData(json, { diff --git a/services/endpoint/endpoint.service.js b/services/endpoint/endpoint.service.js index 26be6f8402..10fc4e0174 100644 --- a/services/endpoint/endpoint.service.js +++ b/services/endpoint/endpoint.service.js @@ -1,6 +1,6 @@ import { URL } from 'url' import Joi from 'joi' -import { errorMessages } from '../dynamic-common.js' +import { httpErrors } from '../dynamic-common.js' import { optionalUrl } from '../validators.js' import { fetchEndpointData } from '../endpoint-common.js' import { BaseJsonService, InvalidParameter } from '../index.js' @@ -178,7 +178,10 @@ export default class Endpoint extends BaseJsonService { logoWidth, logoPosition, style, - cacheSeconds, + // don't allow the user to set cacheSeconds any shorter than this._cacheLength + cacheSeconds: Math.max( + ...[this._cacheLength, cacheSeconds].filter(x => x !== undefined) + ), } } @@ -200,7 +203,7 @@ export default class Endpoint extends BaseJsonService { const validated = await fetchEndpointData(this, { url, - errorMessages, + httpErrors, validationPrettyErrorMessage: 'invalid properties', includeKeys: true, }) diff --git a/services/f-droid/f-droid.service.js b/services/f-droid/f-droid.service.js index 3ce765eb20..33de691533 100644 --- a/services/f-droid/f-droid.service.js +++ b/services/f-droid/f-droid.service.js @@ -53,7 +53,7 @@ export default class FDroid extends BaseJsonService { return this._requestJson({ schema, url, - errorMessages: { + httpErrors: { 403: 'app not found', 404: 'app not found', }, diff --git a/services/factorio-mod-portal/factorio-mod-portal.service.js b/services/factorio-mod-portal/factorio-mod-portal.service.js index 27217d267e..904a7f4a68 100644 --- a/services/factorio-mod-portal/factorio-mod-portal.service.js +++ b/services/factorio-mod-portal/factorio-mod-portal.service.js @@ -29,7 +29,7 @@ class BaseFactorioModPortalService extends BaseJsonService { const { releases, downloads_count } = await this._requestJson({ schema, url: `https://mods.factorio.com/api/mods/${modName}`, - errorMessages: { + httpErrors: { 404: 'mod not found', }, }) diff --git a/services/fedora/fedora.service.js b/services/fedora/fedora.service.js index d869bcd6ef..10c7ee0163 100644 --- a/services/fedora/fedora.service.js +++ b/services/fedora/fedora.service.js @@ -30,7 +30,7 @@ export default class Fedora extends BaseJsonService { url: `https://apps.fedoraproject.org/mdapi/${encodeURIComponent( branch )}/pkg/${encodeURIComponent(packageName)}`, - errorMessages: { + httpErrors: { 400: 'branch not found', }, }) diff --git a/services/feedz/feedz.service.js b/services/feedz/feedz.service.js index 9039f1bf9a..8bd2309194 100644 --- a/services/feedz/feedz.service.js +++ b/services/feedz/feedz.service.js @@ -75,7 +75,7 @@ class FeedzVersionService extends BaseJsonService { return await this._requestJson({ schema: packageSchema, url: `${registrationsBaseUrl}${packageName}/index.json`, - errorMessages: { + httpErrors: { 404: 'repository or package not found', }, }) @@ -90,7 +90,7 @@ class FeedzVersionService extends BaseJsonService { this._requestJson({ schema: singlePageSchema, url: i['@id'], - errorMessages: { + httpErrors: { 404: 'repository or package not found', }, }) diff --git a/services/gem/gem-downloads.service.js b/services/gem/gem-downloads.service.js index 6028530a24..6944fe406b 100644 --- a/services/gem/gem-downloads.service.js +++ b/services/gem/gem-downloads.service.js @@ -88,7 +88,7 @@ export default class GemDownloads extends BaseJsonService { const json = await this._requestJson({ url: `https://rubygems.org/api/v1/versions/${gem}.json`, schema: versionSchema, - errorMessages: { + httpErrors: { 404: 'gem not found', }, }) @@ -117,7 +117,7 @@ export default class GemDownloads extends BaseJsonService { await this._requestJson({ url: `https://rubygems.org/api/v1/gems/${gem}.json`, schema: gemSchema, - errorMessages: { + httpErrors: { 404: 'gem not found', }, }) diff --git a/services/gerrit/gerrit.service.js b/services/gerrit/gerrit.service.js index 04ebca3757..b6271d588a 100644 --- a/services/gerrit/gerrit.service.js +++ b/services/gerrit/gerrit.service.js @@ -64,7 +64,7 @@ export default class Gerrit extends BaseJsonService { return this._requestJson({ schema, url: `${baseUrl}/changes/${changeId}`, - errorMessages: { + httpErrors: { 404: 'change not found', }, }) diff --git a/services/github/gist/github-gist-last-commit.service.js b/services/github/gist/github-gist-last-commit.service.js index cc148a8550..db5c8089cd 100644 --- a/services/github/gist/github-gist-last-commit.service.js +++ b/services/github/gist/github-gist-last-commit.service.js @@ -2,7 +2,7 @@ import Joi from 'joi' import { formatDate } from '../../text-formatters.js' import { age as ageColor } from '../../color-formatters.js' import { GithubAuthV3Service } from '../github-auth-service.js' -import { documentation, errorMessagesFor } from '../github-helpers.js' +import { documentation, httpErrorsFor } from '../github-helpers.js' const schema = Joi.object({ updated_at: Joi.string().required(), @@ -36,7 +36,7 @@ export default class GistLastCommit extends GithubAuthV3Service { return this._requestJson({ url: `/gists/${gistId}`, schema, - errorMessages: errorMessagesFor('gist not found'), + httpErrors: httpErrorsFor('gist not found'), }) } diff --git a/services/github/github-actions-workflow-status.service.js b/services/github/github-actions-workflow-status.service.js index 2c598cc3f5..e3f757fcc6 100644 --- a/services/github/github-actions-workflow-status.service.js +++ b/services/github/github-actions-workflow-status.service.js @@ -85,7 +85,7 @@ export default class GithubActionsWorkflowStatus extends BaseSvgScrapingService )}/badge.svg`, options: { searchParams: { branch, event } }, valueMatcher: />([^<>]+)<\/tspan><\/text><\/g> ` -function errorMessagesFor(notFoundMessage = 'project not found') { +function httpErrorsFor(notFoundMessage = 'project not found') { return { 401: notFoundMessage, 404: notFoundMessage, } } -export { documentation, errorMessagesFor } +export { documentation, httpErrorsFor } diff --git a/services/gitlab/gitlab-issues.service.js b/services/gitlab/gitlab-issues.service.js index ad86069f95..3f88d66519 100644 --- a/services/gitlab/gitlab-issues.service.js +++ b/services/gitlab/gitlab-issues.service.js @@ -1,7 +1,7 @@ import Joi from 'joi' import { optionalUrl, nonNegativeInteger } from '../validators.js' import { metric } from '../text-formatters.js' -import { documentation, errorMessagesFor } from './gitlab-helper.js' +import { documentation, httpErrorsFor } from './gitlab-helper.js' import GitLabBase from './gitlab-base.js' const schema = Joi.object({ @@ -237,7 +237,7 @@ export default class GitlabIssues extends GitLabBase { project )}/issues_statistics`, options: labels ? { searchParams: { labels } } : undefined, - errorMessages: errorMessagesFor('project not found'), + httpErrors: httpErrorsFor('project not found'), }) } diff --git a/services/gitlab/gitlab-languages-count.service.js b/services/gitlab/gitlab-languages-count.service.js index 60e6588e7a..4d08f13b67 100644 --- a/services/gitlab/gitlab-languages-count.service.js +++ b/services/gitlab/gitlab-languages-count.service.js @@ -1,7 +1,7 @@ import Joi from 'joi' import { optionalUrl } from '../validators.js' import { metric } from '../text-formatters.js' -import { documentation, errorMessagesFor } from './gitlab-helper.js' +import { documentation, httpErrorsFor } from './gitlab-helper.js' import GitLabBase from './gitlab-base.js' /* @@ -54,7 +54,7 @@ export default class GitlabLanguageCount extends GitLabBase { url: `${baseUrl}/api/v4/projects/${encodeURIComponent( project )}/languages`, - errorMessages: errorMessagesFor('project not found'), + httpErrors: httpErrorsFor('project not found'), }) } diff --git a/services/gitlab/gitlab-last-commit.service.js b/services/gitlab/gitlab-last-commit.service.js index b2342d669b..c69050dfe4 100644 --- a/services/gitlab/gitlab-last-commit.service.js +++ b/services/gitlab/gitlab-last-commit.service.js @@ -2,7 +2,7 @@ import Joi from 'joi' import { optionalUrl } from '../validators.js' import { formatDate } from '../text-formatters.js' import { age as ageColor } from '../color-formatters.js' -import { documentation, errorMessagesFor } from './gitlab-helper.js' +import { documentation, httpErrorsFor } from './gitlab-helper.js' import GitLabBase from './gitlab-base.js' const schema = Joi.array() @@ -65,7 +65,7 @@ export default class GitlabLastCommit extends GitLabBase { )}/repository/commits`, options: { searchParams: { ref_name: ref } }, schema, - errorMessages: errorMessagesFor('project not found'), + httpErrors: httpErrorsFor('project not found'), }) } diff --git a/services/gitlab/gitlab-license.service.js b/services/gitlab/gitlab-license.service.js index 254696121c..131173ba8a 100644 --- a/services/gitlab/gitlab-license.service.js +++ b/services/gitlab/gitlab-license.service.js @@ -1,7 +1,7 @@ import Joi from 'joi' import { optionalUrl } from '../validators.js' import { renderLicenseBadge } from '../licenses.js' -import { documentation, errorMessagesFor } from './gitlab-helper.js' +import { documentation, httpErrorsFor } from './gitlab-helper.js' import GitLabBase from './gitlab-base.js' const schema = Joi.object({ @@ -67,7 +67,7 @@ export default class GitlabLicense extends GitLabBase { schema, url: `${baseUrl}/api/v4/projects/${encodeURIComponent(project)}`, options: { searchParams: { license: '1' } }, - errorMessages: errorMessagesFor('project not found'), + httpErrors: httpErrorsFor('project not found'), }) } diff --git a/services/gitlab/gitlab-merge-requests.service.js b/services/gitlab/gitlab-merge-requests.service.js index bc7f7b88a1..5db63bcb6e 100644 --- a/services/gitlab/gitlab-merge-requests.service.js +++ b/services/gitlab/gitlab-merge-requests.service.js @@ -1,7 +1,7 @@ import Joi from 'joi' import { optionalUrl, nonNegativeInteger } from '../validators.js' import { metric } from '../text-formatters.js' -import { documentation, errorMessagesFor } from './gitlab-helper.js' +import { documentation, httpErrorsFor } from './gitlab-helper.js' import GitLabBase from './gitlab-base.js' // The total number of MR is in the `x-total` field in the headers. @@ -314,7 +314,7 @@ export default class GitlabMergeRequests extends GitLabBase { labels, }, }, - errorMessages: errorMessagesFor('project not found'), + httpErrors: httpErrorsFor('project not found'), }) ) return this.constructor._validate(res.headers, schema) diff --git a/services/gitlab/gitlab-pipeline-coverage.service.js b/services/gitlab/gitlab-pipeline-coverage.service.js index 3267e8e4eb..e0a332907b 100644 --- a/services/gitlab/gitlab-pipeline-coverage.service.js +++ b/services/gitlab/gitlab-pipeline-coverage.service.js @@ -2,7 +2,7 @@ import Joi from 'joi' import { coveragePercentage } from '../color-formatters.js' import { optionalUrl } from '../validators.js' import { BaseSvgScrapingService, NotFound } from '../index.js' -import { documentation, errorMessagesFor } from './gitlab-helper.js' +import { documentation, httpErrorsFor } from './gitlab-helper.js' const schema = Joi.object({ message: Joi.string() @@ -98,11 +98,11 @@ export default class GitlabPipelineCoverage extends BaseSvgScrapingService { const url = `${baseUrl}/${decodeURIComponent( project )}/badges/${branch}/coverage.svg${jobName}` - const errorMessages = errorMessagesFor('project not found') + const httpErrors = httpErrorsFor('project not found') return this._requestSvg({ schema, url, - errorMessages, + httpErrors, }) } diff --git a/services/gitlab/gitlab-pipeline-status.service.js b/services/gitlab/gitlab-pipeline-status.service.js index dbd0cdbcd1..49246f861d 100644 --- a/services/gitlab/gitlab-pipeline-status.service.js +++ b/services/gitlab/gitlab-pipeline-status.service.js @@ -2,7 +2,7 @@ import Joi from 'joi' import { isBuildStatus, renderBuildStatusBadge } from '../build-status.js' import { optionalUrl } from '../validators.js' import { BaseSvgScrapingService, NotFound, redirector } from '../index.js' -import { documentation, errorMessagesFor } from './gitlab-helper.js' +import { documentation, httpErrorsFor } from './gitlab-helper.js' const badgeSchema = Joi.object({ message: Joi.alternatives() @@ -73,7 +73,7 @@ class GitlabPipelineStatus extends BaseSvgScrapingService { url: `${baseUrl}/${decodeURIComponent( project )}/badges/${branch}/pipeline.svg`, - errorMessages: errorMessagesFor('project not found'), + httpErrors: httpErrorsFor('project not found'), }) } diff --git a/services/gitlab/gitlab-release.service.js b/services/gitlab/gitlab-release.service.js index 51f3c37291..28e3872b0c 100644 --- a/services/gitlab/gitlab-release.service.js +++ b/services/gitlab/gitlab-release.service.js @@ -2,7 +2,7 @@ import Joi from 'joi' import { optionalUrl } from '../validators.js' import { latest, renderVersionBadge } from '../version.js' import { NotFound } from '../index.js' -import { documentation, errorMessagesFor } from './gitlab-helper.js' +import { documentation, httpErrorsFor } from './gitlab-helper.js' import GitLabBase from './gitlab-base.js' const schema = Joi.array().items( @@ -98,7 +98,7 @@ export default class GitLabRelease extends GitLabBase { return this.fetchPaginatedArrayData({ schema, url: `${baseUrl}/api/v4/projects/${encodeURIComponent(project)}/releases`, - errorMessages: errorMessagesFor('project not found'), + httpErrors: httpErrorsFor('project not found'), options: { searchParams: { order_by: orderBy }, }, diff --git a/services/gitlab/gitlab-stars.service.js b/services/gitlab/gitlab-stars.service.js index a440c814f3..695c0db391 100644 --- a/services/gitlab/gitlab-stars.service.js +++ b/services/gitlab/gitlab-stars.service.js @@ -58,7 +58,7 @@ export default class GitlabStars extends GitLabBase { return super.fetch({ schema, url: `${baseUrl}/api/v4/projects/${encodeURIComponent(project)}`, - errorMessages: { + httpErrors: { 404: 'project not found', }, }) diff --git a/services/gitlab/gitlab-tag.service.js b/services/gitlab/gitlab-tag.service.js index 534d371972..10f7bd62ed 100644 --- a/services/gitlab/gitlab-tag.service.js +++ b/services/gitlab/gitlab-tag.service.js @@ -4,7 +4,7 @@ import { optionalUrl } from '../validators.js' import { latest } from '../version.js' import { addv } from '../text-formatters.js' import { NotFound } from '../index.js' -import { documentation, errorMessagesFor } from './gitlab-helper.js' +import { documentation, httpErrorsFor } from './gitlab-helper.js' import GitLabBase from './gitlab-base.js' const schema = Joi.array().items( @@ -92,7 +92,7 @@ export default class GitlabTag extends GitLabBase { project )}/repository/tags`, options: { searchParams: { order_by: 'updated' } }, - errorMessages: errorMessagesFor('project not found'), + httpErrors: httpErrorsFor('project not found'), }) } diff --git a/services/hackernews/hackernews-user-karma.service.js b/services/hackernews/hackernews-user-karma.service.js index 6ff5638ba7..8d37f841f3 100644 --- a/services/hackernews/hackernews-user-karma.service.js +++ b/services/hackernews/hackernews-user-karma.service.js @@ -44,7 +44,7 @@ export default class HackerNewsUserKarma extends BaseJsonService { return this._requestJson({ schema, url: `https://hacker-news.firebaseio.com/v0/user/${id}.json`, - errorMessages: { + httpErrors: { 404: 'user not found', }, }) diff --git a/services/homebrew/homebrew-downloads.service.js b/services/homebrew/homebrew-downloads.service.js index 20e19b23e4..e7989e48b3 100644 --- a/services/homebrew/homebrew-downloads.service.js +++ b/services/homebrew/homebrew-downloads.service.js @@ -53,7 +53,7 @@ export default class HomebrewDownloads extends BaseJsonService { return this._requestJson({ schema, url: `https://formulae.brew.sh/api/formula/${formula}.json`, - errorMessages: { 404: 'formula not found' }, + httpErrors: { 404: 'formula not found' }, }) } diff --git a/services/jenkins/jenkins-base.js b/services/jenkins/jenkins-base.js index 35398c0301..2a52b2d476 100644 --- a/services/jenkins/jenkins-base.js +++ b/services/jenkins/jenkins-base.js @@ -11,14 +11,14 @@ export default class JenkinsBase extends BaseJsonService { url, schema, searchParams, - errorMessages = { 404: 'instance or job not found' }, + httpErrors = { 404: 'instance or job not found' }, }) { return this._requestJson( this.authHelper.withBasicAuth({ url, options: { searchParams }, schema, - errorMessages, + httpErrors, }) ) } diff --git a/services/jenkins/jenkins-coverage.service.js b/services/jenkins/jenkins-coverage.service.js index 9727fdca4b..c072abe7c2 100644 --- a/services/jenkins/jenkins-coverage.service.js +++ b/services/jenkins/jenkins-coverage.service.js @@ -138,7 +138,7 @@ export default class JenkinsCoverage extends JenkinsBase { url: buildUrl({ jobUrl, plugin: pluginSpecificPath }), schema, searchParams: buildTreeParamQueryString(treeQueryParam), - errorMessages: { + httpErrors: { 404: 'job or coverage not found', }, }) diff --git a/services/jenkins/jenkins-plugin-installs.service.js b/services/jenkins/jenkins-plugin-installs.service.js index 456d2071b6..ce51df1718 100644 --- a/services/jenkins/jenkins-plugin-installs.service.js +++ b/services/jenkins/jenkins-plugin-installs.service.js @@ -63,7 +63,7 @@ export default class JenkinsPluginInstalls extends BaseJsonService { return this._requestJson({ url: `https://stats.jenkins.io/plugin-installation-trend/${plugin}.stats.json`, schema: version ? schemaInstallationsPerVersion : schemaInstallations, - errorMessages: { + httpErrors: { 404: 'plugin not found', }, }) diff --git a/services/jetbrains/jetbrains-base.js b/services/jetbrains/jetbrains-base.js index ea8bc5d5c1..fe3c497c47 100644 --- a/services/jetbrains/jetbrains-base.js +++ b/services/jetbrains/jetbrains-base.js @@ -54,7 +54,7 @@ export default class JetbrainsBase extends BaseXmlService { return super._validate(data, schema) } - async _requestJson({ schema, url, options = {}, errorMessages = {} }) { + async _requestJson({ schema, url, options = {}, httpErrors = {} }) { const mergedOptions = { ...{ headers: { Accept: 'application/json' } }, ...options, @@ -62,7 +62,7 @@ export default class JetbrainsBase extends BaseXmlService { const { buffer } = await this._request({ url, options: mergedOptions, - errorMessages, + httpErrors, }) const json = this._parseJson(buffer) return this.constructor._validateJson(json, schema) diff --git a/services/jetbrains/jetbrains-downloads.service.js b/services/jetbrains/jetbrains-downloads.service.js index fc91c78ce3..7db2403e28 100644 --- a/services/jetbrains/jetbrains-downloads.service.js +++ b/services/jetbrains/jetbrains-downloads.service.js @@ -56,7 +56,7 @@ export default class JetbrainsDownloads extends JetbrainsBase { url: `https://plugins.jetbrains.com/api/plugins/${this.constructor._cleanPluginId( pluginId )}`, - errorMessages: { 400: 'not found' }, + httpErrors: { 400: 'not found' }, }) downloads = jetbrainsPluginData.downloads } diff --git a/services/jetbrains/jetbrains-rating.service.js b/services/jetbrains/jetbrains-rating.service.js index 81fa3fb61b..5c3fd2d757 100644 --- a/services/jetbrains/jetbrains-rating.service.js +++ b/services/jetbrains/jetbrains-rating.service.js @@ -92,7 +92,7 @@ export default class JetbrainsRating extends JetbrainsBase { url: `https://plugins.jetbrains.com/api/plugins/${this.constructor._cleanPluginId( pluginId )}/rating`, - errorMessages: { 400: 'not found' }, + httpErrors: { 400: 'not found' }, }) let voteSum = 0 diff --git a/services/jetbrains/jetbrains-version.service.js b/services/jetbrains/jetbrains-version.service.js index 2b7d8dd3b2..dad18b10a9 100644 --- a/services/jetbrains/jetbrains-version.service.js +++ b/services/jetbrains/jetbrains-version.service.js @@ -67,7 +67,7 @@ export default class JetbrainsVersion extends JetbrainsBase { url: `https://plugins.jetbrains.com/api/plugins/${this.constructor._cleanPluginId( pluginId )}/updates`, - errorMessages: { 400: 'not found' }, + httpErrors: { 400: 'not found' }, }) version = jetbrainsPluginData[0].version } diff --git a/services/jira/jira-issue.service.js b/services/jira/jira-issue.service.js index 35fafa60a3..609c81dd1d 100644 --- a/services/jira/jira-issue.service.js +++ b/services/jira/jira-issue.service.js @@ -75,7 +75,7 @@ export default class JiraIssue extends BaseJsonService { this.authHelper.withBasicAuth({ schema, url: `${baseUrl}/rest/api/2/issue/${encodeURIComponent(issueKey)}`, - errorMessages: { 404: 'issue not found' }, + httpErrors: { 404: 'issue not found' }, }) ) diff --git a/services/jira/jira-sprint.service.js b/services/jira/jira-sprint.service.js index eaf6b0bcc3..2ab4d31a67 100644 --- a/services/jira/jira-sprint.service.js +++ b/services/jira/jira-sprint.service.js @@ -92,7 +92,7 @@ export default class JiraSprint extends BaseJsonService { maxResults: 500, }, }, - errorMessages: { + httpErrors: { 400: 'sprint not found', 404: 'sprint not found', }, diff --git a/services/jitpack/jitpack-version.service.js b/services/jitpack/jitpack-version.service.js index 8420ee58c0..7b088dbffe 100644 --- a/services/jitpack/jitpack-version.service.js +++ b/services/jitpack/jitpack-version.service.js @@ -37,7 +37,7 @@ export default class JitPackVersion extends BaseJsonService { return this._requestJson({ schema, url, - errorMessages: { 401: 'project not found or private' }, + httpErrors: { 401: 'project not found or private' }, }) } diff --git a/services/librariesio/librariesio-base.js b/services/librariesio/librariesio-base.js index 26183df917..850db1e63b 100644 --- a/services/librariesio/librariesio-base.js +++ b/services/librariesio/librariesio-base.js @@ -26,7 +26,7 @@ export default class LibrariesIoBase extends BaseJsonService { url: `/${encodeURIComponent(platform)}/${ scope ? encodeURIComponent(`${scope}/`) : '' }${encodeURIComponent(packageName)}`, - errorMessages: { 404: 'package not found' }, + httpErrors: { 404: 'package not found' }, }) } } diff --git a/services/librariesio/librariesio-dependencies.service.js b/services/librariesio/librariesio-dependencies.service.js index 6c8190534d..5e12a48033 100644 --- a/services/librariesio/librariesio-dependencies.service.js +++ b/services/librariesio/librariesio-dependencies.service.js @@ -92,7 +92,7 @@ class LibrariesIoProjectDependencies extends LibrariesIoBase { const json = await this._requestJson({ url, schema, - errorMessages: { 404: 'package or version not found' }, + httpErrors: { 404: 'package or version not found' }, }) const { deprecatedCount, outdatedCount } = transform(json) return renderDependenciesBadge({ deprecatedCount, outdatedCount }) @@ -127,7 +127,7 @@ class LibrariesIoRepoDependencies extends LibrariesIoBase { const json = await this._requestJson({ url, schema, - errorMessages: { + httpErrors: { 404: 'repo not found', }, }) diff --git a/services/localizely/localizely.service.js b/services/localizely/localizely.service.js index 47c301453b..1dc13f9478 100644 --- a/services/localizely/localizely.service.js +++ b/services/localizely/localizely.service.js @@ -111,7 +111,7 @@ export default class Localizely extends BaseJsonService { searchParams: { branch }, headers: { 'X-Api-Token': apiToken }, }, - errorMessages: { + httpErrors: { 403: 'not authorized for project', }, }) diff --git a/services/luarocks/luarocks.service.js b/services/luarocks/luarocks.service.js index 2ffb68616a..49d75fbe4b 100644 --- a/services/luarocks/luarocks.service.js +++ b/services/luarocks/luarocks.service.js @@ -60,7 +60,7 @@ export default class Luarocks extends BaseJsonService { user )}/manifest.json`, schema, - errorMessages: { + httpErrors: { 404: 'user not found', }, }) diff --git a/services/matrix/matrix.service.js b/services/matrix/matrix.service.js index 50c28ad847..8371388e02 100644 --- a/services/matrix/matrix.service.js +++ b/services/matrix/matrix.service.js @@ -116,7 +116,7 @@ export default class Matrix extends BaseJsonService { auth: { type: 'm.login.dummy' }, }), }, - errorMessages: { + httpErrors: { 401: 'auth failed', 403: 'guests not allowed', }, @@ -134,7 +134,7 @@ export default class Matrix extends BaseJsonService { access_token: accessToken, }, }, - errorMessages: { + httpErrors: { 401: 'bad auth token', 404: 'room not found', }, @@ -172,7 +172,7 @@ export default class Matrix extends BaseJsonService { access_token: accessToken, }, }, - errorMessages: { + httpErrors: { 400: 'unknown request', 401: 'bad auth token', 403: 'room not world readable or is invalid', diff --git a/services/nexus/nexus.service.js b/services/nexus/nexus.service.js index 8f13df2b46..b2b166a719 100644 --- a/services/nexus/nexus.service.js +++ b/services/nexus/nexus.service.js @@ -220,7 +220,7 @@ export default class Nexus extends BaseJsonService { schema, url, options: { searchParams }, - errorMessages: { + httpErrors: { 404: 'artifact not found', }, }) @@ -261,7 +261,7 @@ export default class Nexus extends BaseJsonService { schema: nexus3SearchApiSchema, url, options: { searchParams }, - errorMessages: { + httpErrors: { 404: 'artifact not found', }, }) diff --git a/services/npm/npm-base.js b/services/npm/npm-base.js index 7f8ed6cbc2..b4dc250d62 100644 --- a/services/npm/npm-base.js +++ b/services/npm/npm-base.js @@ -117,7 +117,7 @@ export default class NpmBase extends BaseJsonService { // We don't validate here because we need to pluck the desired subkey first. schema: Joi.any(), url, - errorMessages: { 404: 'package not found' }, + httpErrors: { 404: 'package not found' }, }) let packageData diff --git a/services/npm/npm-downloads.service.js b/services/npm/npm-downloads.service.js index 9745b5db53..ea6ea7eefc 100644 --- a/services/npm/npm-downloads.service.js +++ b/services/npm/npm-downloads.service.js @@ -77,7 +77,7 @@ export default class NpmDownloads extends BaseJsonService { const json = await this._requestJson({ schema, url: `https://api.npmjs.org/downloads/${query}/${slug}`, - errorMessages: { 404: 'package not found or too new' }, + httpErrors: { 404: 'package not found or too new' }, }) const downloadCount = transform(json) diff --git a/services/npm/npm-version.service.js b/services/npm/npm-version.service.js index 20caf3e998..80fd3c9e09 100644 --- a/services/npm/npm-version.service.js +++ b/services/npm/npm-version.service.js @@ -80,7 +80,7 @@ export default class NpmVersion extends NpmBase { const packageData = await this._requestJson({ schema, url: `${registryUrl}/-/package/${slug}/dist-tags`, - errorMessages: { 404: 'package not found' }, + httpErrors: { 404: 'package not found' }, }) if (tag && !(tag in packageData)) { diff --git a/services/npms-io/npms-io-score.service.js b/services/npms-io/npms-io-score.service.js index b0f4891089..6de07aa4dd 100644 --- a/services/npms-io/npms-io-score.service.js +++ b/services/npms-io/npms-io-score.service.js @@ -77,7 +77,7 @@ export default class NpmsIOScore extends BaseJsonService { const json = await this._requestJson({ schema: responseSchema, url, - errorMessages: { 404: 'package not found or too new' }, + httpErrors: { 404: 'package not found or too new' }, }) const scoreType = type.slice(0, -6) diff --git a/services/open-vsx/open-vsx-base.js b/services/open-vsx/open-vsx-base.js index d17a1e66a8..b7a7965660 100644 --- a/services/open-vsx/open-vsx-base.js +++ b/services/open-vsx/open-vsx-base.js @@ -34,7 +34,7 @@ export default class OpenVSXBase extends BaseJsonService { url: `https://open-vsx.org/api/${namespace}/${extension}/${ version || '' }`, - errorMessages: { + httpErrors: { 400: 'invalid extension id', 404: 'extension not found', }, diff --git a/services/opencollective/opencollective-base.js b/services/opencollective/opencollective-base.js index 9019820997..203cfabf03 100644 --- a/services/opencollective/opencollective-base.js +++ b/services/opencollective/opencollective-base.js @@ -43,7 +43,7 @@ export default class OpencollectiveBase extends BaseJsonService { schema: collectiveDetailsSchema, // https://developer.opencollective.com/#/api/collectives?id=get-info url: `https://opencollective.com/${collective}.json`, - errorMessages: { + httpErrors: { 404: 'collective not found', }, }) @@ -66,7 +66,7 @@ export default class OpencollectiveBase extends BaseJsonService { url: `https://opencollective.com/${collective}/members/${ userType || 'all' }.json${tierId ? `?TierId=${tierId}` : ''}`, - errorMessages: { + httpErrors: { 404: 'collective not found', }, }) diff --git a/services/opm/opm-version.service.js b/services/opm/opm-version.service.js index b0c8b5e7fe..e053588628 100644 --- a/services/opm/opm-version.service.js +++ b/services/opm/opm-version.service.js @@ -34,7 +34,7 @@ export default class OpmVersion extends BaseService { name: moduleName, }, }, - errorMessages: { + httpErrors: { 404: 'module not found', }, }) diff --git a/services/ossf-scorecard/ossf-scorecard.service.js b/services/ossf-scorecard/ossf-scorecard.service.js index a7489bcd67..9d17322943 100644 --- a/services/ossf-scorecard/ossf-scorecard.service.js +++ b/services/ossf-scorecard/ossf-scorecard.service.js @@ -41,7 +41,7 @@ export default class OSSFScorecard extends BaseJsonService { return this._requestJson({ schema, url: `https://api.securityscorecards.dev/projects/${host}/${orgName}/${repoName}`, - errorMessages: { + httpErrors: { 404: 'invalid repo path', }, }) diff --git a/services/piwheels/piwheels-version.service.js b/services/piwheels/piwheels-version.service.js index 51be963d6e..b83e341c03 100644 --- a/services/piwheels/piwheels-version.service.js +++ b/services/piwheels/piwheels-version.service.js @@ -55,7 +55,7 @@ export default class PiWheelsVersion extends BaseJsonService { return this._requestJson({ schema, url: `https://www.piwheels.org/project/${wheel}/json/`, - errorMessages: { 404: 'package not found' }, + httpErrors: { 404: 'package not found' }, }) } diff --git a/services/pypi/pypi-base.js b/services/pypi/pypi-base.js index 012af06f49..48f7e43f83 100644 --- a/services/pypi/pypi-base.js +++ b/services/pypi/pypi-base.js @@ -30,7 +30,7 @@ export default class PypiBase extends BaseJsonService { return this._requestJson({ schema, url: `https://pypi.org/pypi/${egg}/json`, - errorMessages: { 404: 'package or version not found' }, + httpErrors: { 404: 'package or version not found' }, }) } } diff --git a/services/pypi/pypi-downloads.service.js b/services/pypi/pypi-downloads.service.js index abc0647f30..d6449bcdcd 100644 --- a/services/pypi/pypi-downloads.service.js +++ b/services/pypi/pypi-downloads.service.js @@ -59,7 +59,7 @@ export default class PypiDownloads extends BaseJsonService { return this._requestJson({ url: `https://pypistats.org/api/packages/${packageName.toLowerCase()}/recent`, schema, - errorMessages: { 404: 'package not found' }, + httpErrors: { 404: 'package not found' }, }) } diff --git a/services/reddit/subreddit-subscribers.service.js b/services/reddit/subreddit-subscribers.service.js index 2d0ce5c53d..d162e6fd0c 100644 --- a/services/reddit/subreddit-subscribers.service.js +++ b/services/reddit/subreddit-subscribers.service.js @@ -48,7 +48,7 @@ export default class RedditSubredditSubscribers extends BaseJsonService { return this._requestJson({ schema, url: `https://www.reddit.com/r/${subreddit}/about.json`, - errorMessages: { + httpErrors: { 404: 'subreddit not found', 403: 'subreddit is private', }, diff --git a/services/reddit/user-karma.service.js b/services/reddit/user-karma.service.js index b53edfc68a..fe873aa046 100644 --- a/services/reddit/user-karma.service.js +++ b/services/reddit/user-karma.service.js @@ -53,7 +53,7 @@ export default class RedditUserKarma extends BaseJsonService { return this._requestJson({ schema, url: `https://www.reddit.com/u/${user}/about.json`, - errorMessages: { + httpErrors: { 404: 'user not found', }, }) diff --git a/services/reuse/reuse-compliance.service.js b/services/reuse/reuse-compliance.service.js index 93933f5f90..2473572d37 100644 --- a/services/reuse/reuse-compliance.service.js +++ b/services/reuse/reuse-compliance.service.js @@ -41,7 +41,7 @@ export default class Reuse extends BaseJsonService { return await this._requestJson({ schema: responseSchema, url: `https://api.reuse.software/status/${remote}`, - errorMessages: { + httpErrors: { 400: 'Not a Git repository', }, }) diff --git a/services/scrutinizer/scrutinizer-base.js b/services/scrutinizer/scrutinizer-base.js index 918a9b6dec..90f4fe9062 100644 --- a/services/scrutinizer/scrutinizer-base.js +++ b/services/scrutinizer/scrutinizer-base.js @@ -6,7 +6,7 @@ export default class ScrutinizerBase extends BaseJsonService { return this._requestJson({ schema, url: `https://scrutinizer-ci.com/api/repositories/${vcs}/${slug}`, - errorMessages: { + httpErrors: { 401: 'not authorized to access project', 404: 'project not found', }, diff --git a/services/snyk/snyk-vulnerability-base.js b/services/snyk/snyk-vulnerability-base.js index 39a5fd33f9..ee25d1dd44 100644 --- a/services/snyk/snyk-vulnerability-base.js +++ b/services/snyk/snyk-vulnerability-base.js @@ -25,14 +25,14 @@ export default class SnykVulnerabilityBase extends BaseSvgScrapingService { } } - async fetch({ url, searchParams, errorMessages }) { + async fetch({ url, searchParams, httpErrors }) { const { message: vulnerabilities } = await this._requestSvg({ url, schema, options: { searchParams, }, - errorMessages, + httpErrors, }) return { vulnerabilities } diff --git a/services/snyk/snyk-vulnerability-github.service.js b/services/snyk/snyk-vulnerability-github.service.js index 535dc31114..7611e4ffd4 100644 --- a/services/snyk/snyk-vulnerability-github.service.js +++ b/services/snyk/snyk-vulnerability-github.service.js @@ -39,7 +39,7 @@ export default class SnykVulnerabilityGitHub extends SynkVulnerabilityBase { const { vulnerabilities } = await this.fetch({ url, searchParams, - errorMessages: { + httpErrors: { 404: 'repo or manifest not found', }, }) diff --git a/services/snyk/snyk-vulnerability-npm.service.js b/services/snyk/snyk-vulnerability-npm.service.js index 4e5f99db3e..5043608400 100644 --- a/services/snyk/snyk-vulnerability-npm.service.js +++ b/services/snyk/snyk-vulnerability-npm.service.js @@ -43,7 +43,7 @@ export default class SnykVulnerabilityNpm extends SynkVulnerabilityBase { // Snyk returns an HTTP 200 with an HTML page when the specified // npm package is not found that contains the text 404. // Including this in case Snyk starts returning a 404 response code instead. - errorMessages: { + httpErrors: { 404: 'npm package is invalid or does not exist', }, }) diff --git a/services/sonar/sonar-base.js b/services/sonar/sonar-base.js index 2e4fd807ca..aaa29d3346 100644 --- a/services/sonar/sonar-base.js +++ b/services/sonar/sonar-base.js @@ -84,7 +84,7 @@ export default class SonarBase extends BaseJsonService { schema, url, options: { searchParams }, - errorMessages: { + httpErrors: { 404: 'component or metric not found, or legacy API not supported', }, }) diff --git a/services/sourceforge/sourceforge-base.js b/services/sourceforge/sourceforge-base.js index c8e84ed0df..e1c973a8cf 100644 --- a/services/sourceforge/sourceforge-base.js +++ b/services/sourceforge/sourceforge-base.js @@ -5,7 +5,7 @@ export default class BaseSourceForgeService extends BaseJsonService { return this._requestJson({ url: `https://sourceforge.net/rest/p/${project}/`, schema, - errorMessages: { + httpErrors: { 404: 'project not found', }, }) diff --git a/services/sourceforge/sourceforge-commit-count.service.js b/services/sourceforge/sourceforge-commit-count.service.js index 581f4384c2..d7c9f89275 100644 --- a/services/sourceforge/sourceforge-commit-count.service.js +++ b/services/sourceforge/sourceforge-commit-count.service.js @@ -39,7 +39,7 @@ export default class SourceforgeCommitCount extends BaseJsonService { return this._requestJson({ url: `https://sourceforge.net/rest/p/${project}/git`, schema, - errorMessages: { + httpErrors: { 404: 'project not found', }, }) diff --git a/services/sourceforge/sourceforge-downloads.service.js b/services/sourceforge/sourceforge-downloads.service.js index f382b5c1e2..134c52f20c 100644 --- a/services/sourceforge/sourceforge-downloads.service.js +++ b/services/sourceforge/sourceforge-downloads.service.js @@ -91,7 +91,7 @@ export default class SourceforgeDownloads extends BaseJsonService { schema, url, options, - errorMessages: { + httpErrors: { 404: 'project not found', }, }) diff --git a/services/sourceforge/sourceforge-last-commit.service.js b/services/sourceforge/sourceforge-last-commit.service.js index 9e6acfb38f..5b4315af6f 100644 --- a/services/sourceforge/sourceforge-last-commit.service.js +++ b/services/sourceforge/sourceforge-last-commit.service.js @@ -46,7 +46,7 @@ export default class SourceforgeLastCommit extends BaseJsonService { return this._requestJson({ url: `https://sourceforge.net/rest/p/${project}/git/commits`, schema, - errorMessages: { + httpErrors: { 404: 'project not found', }, }) diff --git a/services/sourceforge/sourceforge-open-tickets.service.js b/services/sourceforge/sourceforge-open-tickets.service.js index 7cf956105b..d6fa6b2c26 100644 --- a/services/sourceforge/sourceforge-open-tickets.service.js +++ b/services/sourceforge/sourceforge-open-tickets.service.js @@ -43,7 +43,7 @@ export default class SourceforgeOpenTickets extends BaseJsonService { return this._requestJson({ schema, url, - errorMessages: { + httpErrors: { 404: 'project not found', }, }) diff --git a/services/spack/spack.service.js b/services/spack/spack.service.js index c3ad8e527f..a052431d74 100644 --- a/services/spack/spack.service.js +++ b/services/spack/spack.service.js @@ -32,7 +32,7 @@ export default class SpackVersion extends BaseJsonService { return this._requestJson({ schema, url: `https://packages.spack.io/data/packages/${packageName}.json`, - errorMessages: { + httpErrors: { 404: 'package not found', }, }) diff --git a/services/stackexchange/stackexchange-reputation.service.js b/services/stackexchange/stackexchange-reputation.service.js index db2e3df40d..b75f61e39e 100644 --- a/services/stackexchange/stackexchange-reputation.service.js +++ b/services/stackexchange/stackexchange-reputation.service.js @@ -49,7 +49,7 @@ export default class StackExchangeReputation extends StackExchangeBase { schema: reputationSchema, options: { decompress: true, searchParams: { site: stackexchangesite } }, url: `https://api.stackexchange.com/2.2/${path}`, - errorMessages: { + httpErrors: { 400: 'invalid parameters', }, }) diff --git a/services/steam/steam-base.js b/services/steam/steam-base.js index 9ea5cae989..459c6d2a7a 100644 --- a/services/steam/steam-base.js +++ b/services/steam/steam-base.js @@ -45,7 +45,7 @@ class BaseSteamAPI extends BaseJsonService { return this._requestJson({ url, schema, - errorMessages: { + httpErrors: { 400: 'bad request', }, options, diff --git a/services/symfony/symfony-insight-base.js b/services/symfony/symfony-insight-base.js index 8cace75a89..95318439af 100644 --- a/services/symfony/symfony-insight-base.js +++ b/services/symfony/symfony-insight-base.js @@ -62,7 +62,7 @@ class SymfonyInsightBase extends BaseXmlService { options: { headers: { Accept: 'application/vnd.com.sensiolabs.insight+xml' }, }, - errorMessages: { + httpErrors: { 401: 'not authorized to access project', 404: 'project not found', }, diff --git a/services/tas/tas-tests.service.js b/services/tas/tas-tests.service.js index b347f8caaa..70836b0f7c 100644 --- a/services/tas/tas-tests.service.js +++ b/services/tas/tas-tests.service.js @@ -80,7 +80,7 @@ export default class TasBuildStatus extends BaseJsonService { return this._requestJson({ schema, url: `https://api.tas.lambdatest.com/repo/badge?git_provider=${provider}&org=${org}&repo=${repo}`, - errorMessages: { + httpErrors: { 401: 'private project not supported', 404: 'project not found', }, diff --git a/services/teamcity/teamcity-base.js b/services/teamcity/teamcity-base.js index a3b447c72d..00b60da40b 100644 --- a/services/teamcity/teamcity-base.js +++ b/services/teamcity/teamcity-base.js @@ -7,7 +7,7 @@ export default class TeamCityBase extends BaseJsonService { serviceKey: 'teamcity', } - async fetch({ url, schema, searchParams = {}, errorMessages = {} }) { + async fetch({ url, schema, searchParams = {}, httpErrors = {} }) { // JetBrains API Auth Docs: https://confluence.jetbrains.com/display/TCD18/REST+API#RESTAPI-RESTAuthentication const options = { searchParams } if (!this.authHelper.isConfigured) { @@ -19,7 +19,7 @@ export default class TeamCityBase extends BaseJsonService { url, schema, options, - errorMessages: { 404: 'build not found', ...errorMessages }, + httpErrors: { 404: 'build not found', ...httpErrors }, }) ) } diff --git a/services/testspace/testspace-base.js b/services/testspace/testspace-base.js index 5f74c556a0..556aaf2b7f 100644 --- a/services/testspace/testspace-base.js +++ b/services/testspace/testspace-base.js @@ -35,7 +35,7 @@ export default class TestspaceBase extends BaseJsonService { return this._requestJson({ schema, url, - errorMessages: { + httpErrors: { 403: 'org not found or not authorized', 404: 'org, project, or space not found', }, diff --git a/services/tokei/tokei.service.js b/services/tokei/tokei.service.js index dd01918b8d..2a6baeb8c5 100644 --- a/services/tokei/tokei.service.js +++ b/services/tokei/tokei.service.js @@ -65,7 +65,7 @@ export default class Tokei extends BaseJsonService { return this._requestJson({ schema, url: `https://tokei.rs/b1/${provider}/${user}/${repo}`, - errorMessages: { + httpErrors: { 400: 'repo not found', }, }) diff --git a/services/twitch/twitch-base.js b/services/twitch/twitch-base.js index 844157c3f1..3ca2b135a0 100644 --- a/services/twitch/twitch-base.js +++ b/services/twitch/twitch-base.js @@ -46,7 +46,7 @@ export default class TwitchBase extends BaseJsonService { grant_type: 'client_credentials', }, }, - errorMessages: { + httpErrors: { 401: 'invalid token', 404: 'node not found', }, diff --git a/services/ubuntu/ubuntu.service.js b/services/ubuntu/ubuntu.service.js index a52d61b14b..fae6f52837 100644 --- a/services/ubuntu/ubuntu.service.js +++ b/services/ubuntu/ubuntu.service.js @@ -53,7 +53,7 @@ export default class Ubuntu extends BaseJsonService { ...seriesParam, }, }, - errorMessages: { + httpErrors: { 400: 'series not found', }, }) diff --git a/services/visual-studio-app-center/visual-studio-app-center-base.js b/services/visual-studio-app-center/visual-studio-app-center-base.js index e90a6ee2f3..72952155d5 100644 --- a/services/visual-studio-app-center/visual-studio-app-center-base.js +++ b/services/visual-studio-app-center/visual-studio-app-center-base.js @@ -25,7 +25,7 @@ class BaseVisualStudioAppCenterService extends BaseJsonService { 'X-API-Token': token, }, }, - errorMessages: { + httpErrors: { 401: 'invalid token', 403: 'project not found', 404: 'project not found', diff --git a/services/visual-studio-marketplace/visual-studio-marketplace-base.js b/services/visual-studio-marketplace/visual-studio-marketplace-base.js index 95acda7747..53456a91df 100644 --- a/services/visual-studio-marketplace/visual-studio-marketplace-base.js +++ b/services/visual-studio-marketplace/visual-studio-marketplace-base.js @@ -95,7 +95,7 @@ export default class VisualStudioMarketplaceBase extends BaseJsonService { schema: extensionQuerySchema, url, options, - errorMessages: { + httpErrors: { 400: 'invalid extension id', }, }) diff --git a/services/weblate/weblate-component-license.service.js b/services/weblate/weblate-component-license.service.js index a24f5c3ab9..2a31fa8b5c 100644 --- a/services/weblate/weblate-component-license.service.js +++ b/services/weblate/weblate-component-license.service.js @@ -37,7 +37,7 @@ export default class WeblateComponentLicense extends WeblateBase { return super.fetch({ schema, url: `${server}/api/components/${project}/${component}/`, - errorMessages: { + httpErrors: { 403: 'access denied by remote server', 404: 'component not found', }, diff --git a/services/weblate/weblate-entities.service.js b/services/weblate/weblate-entities.service.js index f8db2d25ca..26f59b4774 100644 --- a/services/weblate/weblate-entities.service.js +++ b/services/weblate/weblate-entities.service.js @@ -36,7 +36,7 @@ export default class WeblateEntities extends WeblateBase { return super.fetch({ schema, url: `${server}/api/${type}/`, - errorMessages: { + httpErrors: { 403: 'access denied by remote server', }, }) diff --git a/services/weblate/weblate-project-translated-percentage.service.js b/services/weblate/weblate-project-translated-percentage.service.js index e8089f3b37..d9743b03c3 100644 --- a/services/weblate/weblate-project-translated-percentage.service.js +++ b/services/weblate/weblate-project-translated-percentage.service.js @@ -49,7 +49,7 @@ export default class WeblateProjectTranslatedPercentage extends WeblateBase { return super.fetch({ schema, url: `${server}/api/projects/${project}/statistics/`, - errorMessages: { + httpErrors: { 403: 'access denied by remote server', 404: 'project not found', }, diff --git a/services/weblate/weblate-user-statistic.service.js b/services/weblate/weblate-user-statistic.service.js index 639153bc68..6a4c3a89dc 100644 --- a/services/weblate/weblate-user-statistic.service.js +++ b/services/weblate/weblate-user-statistic.service.js @@ -49,7 +49,7 @@ export default class WeblateUserStatistic extends WeblateBase { return super.fetch({ schema, url: `${server}/api/users/${user}/statistics/`, - errorMessages: { + httpErrors: { 403: 'access denied by remote server', 404: 'user not found', }, diff --git a/services/wheelmap/wheelmap.service.js b/services/wheelmap/wheelmap.service.js index c6abf22d8c..98a43ef1d4 100644 --- a/services/wheelmap/wheelmap.service.js +++ b/services/wheelmap/wheelmap.service.js @@ -50,7 +50,7 @@ export default class Wheelmap extends BaseJsonService { { schema, url: `https://wheelmap.org/api/nodes/${nodeId}`, - errorMessages: { + httpErrors: { 401: 'invalid token', 404: 'node not found', },