diff --git a/lib/logger/__snapshots__/err-serializer.spec.ts.snap b/lib/logger/__snapshots__/err-serializer.spec.ts.snap index 0c52aefaf7c915..add99c1ad25a3d 100644 --- a/lib/logger/__snapshots__/err-serializer.spec.ts.snap +++ b/lib/logger/__snapshots__/err-serializer.spec.ts.snap @@ -27,7 +27,7 @@ exports[`logger/err-serializer > got > sanitize http error 1`] = ` "headers": { "content-type": "application/json", }, - "httpVersion": null, + "httpVersion": "1.1", "retryCount": 0, "statusCode": 412, "statusMessage": "Precondition Failed", diff --git a/lib/modules/datasource/docker/index.spec.ts b/lib/modules/datasource/docker/index.spec.ts index b54ec66d8dfd51..db86ea3d0cc484 100644 --- a/lib/modules/datasource/docker/index.spec.ts +++ b/lib/modules/datasource/docker/index.spec.ts @@ -651,14 +651,20 @@ describe('modules/datasource/docker/index', () => { }); it('should throw error for 429', async () => { - httpMock.scope(baseUrl).get('/').replyWithError({ statusCode: 429 }); + httpMock + .scope(baseUrl) + .get('/') + .replyWithError(httpMock.error({ statusCode: 429 })); await expect( getDigest({ datasource: 'docker', packageName: 'some-dep' }, 'latest'), ).rejects.toThrow(EXTERNAL_HOST_ERROR); }); it('should throw error for 5xx', async () => { - httpMock.scope(baseUrl).get('/').replyWithError({ statusCode: 504 }); + httpMock + .scope(baseUrl) + .get('/') + .replyWithError(httpMock.error({ statusCode: 504 })); await expect( getDigest({ datasource: 'docker', packageName: 'some-dep' }, 'latest'), ).rejects.toThrow(EXTERNAL_HOST_ERROR); diff --git a/lib/modules/datasource/npm/get.spec.ts b/lib/modules/datasource/npm/get.spec.ts index 202158a06e7d8a..70dac92c3a8f0b 100644 --- a/lib/modules/datasource/npm/get.spec.ts +++ b/lib/modules/datasource/npm/get.spec.ts @@ -362,6 +362,7 @@ describe('modules/datasource/npm/get', () => { "accept": "application/json", "accept-encoding": "gzip, deflate, br", "authorization": "Bearer XXX", + "connection": "close", "host": "test.org", "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", }, @@ -509,6 +510,7 @@ describe('modules/datasource/npm/get', () => { "accept": "application/json", "accept-encoding": "gzip, deflate, br", "authorization": "Bearer XXX", + "connection": "close", "host": "test.org", "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", }, @@ -550,6 +552,7 @@ describe('modules/datasource/npm/get', () => { "accept": "application/json", "accept-encoding": "gzip, deflate, br", "authorization": "Bearer XXX", + "connection": "close", "host": "test.org", "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", }, diff --git a/lib/modules/datasource/packagist/index.spec.ts b/lib/modules/datasource/packagist/index.spec.ts index c2ddeca8b0df7c..dd69e46f393f86 100644 --- a/lib/modules/datasource/packagist/index.spec.ts +++ b/lib/modules/datasource/packagist/index.spec.ts @@ -81,7 +81,7 @@ describe('modules/datasource/packagist/index', () => { httpMock .scope('https://composer.renovatebot.com') .get('/packages.json') - .replyWithError({ code: 'ETIMEDOUT' }); + .replyWithError(httpMock.error({ code: 'ETIMEDOUT' })); httpMock .scope(baseUrl) .get('/packages.json') diff --git a/lib/modules/datasource/repology/index.spec.ts b/lib/modules/datasource/repology/index.spec.ts index e532ab6aa1bf66..78077440c0a71d 100644 --- a/lib/modules/datasource/repology/index.spec.ts +++ b/lib/modules/datasource/repology/index.spec.ts @@ -24,7 +24,7 @@ const mockApiCall = (name: string, response: ResponseMock) => { if (response.status) { interceptor.reply(response.status, response.body); } else { - interceptor.replyWithError({ code: response.code }); + interceptor.replyWithError(httpMock.error({ code: response.code })); } }; @@ -49,7 +49,7 @@ const mockResolverCall = ( if (response.status) { interceptor.reply(response.status, response.body); } else { - interceptor.replyWithError({ code: response.code }); + interceptor.replyWithError(httpMock.error({ code: response.code })); } }; diff --git a/lib/modules/platform/gitea/index.spec.ts b/lib/modules/platform/gitea/index.spec.ts index 0d7224b8ebfb8e..74ee08da8bd135 100644 --- a/lib/modules/platform/gitea/index.spec.ts +++ b/lib/modules/platform/gitea/index.spec.ts @@ -356,7 +356,7 @@ describe('modules/platform/gitea/index', () => { uid: 1, archived: false, }) - .replyWithError(new Error('searchRepos()')); + .replyWithError(httpMock.error('searchRepos()')); await initFakePlatform(scope); await expect(gitea.getRepos()).rejects.toThrow('searchRepos()'); @@ -464,7 +464,7 @@ describe('modules/platform/gitea/index', () => { const scope = httpMock .scope('https://gitea.com/api/v1') .get(`/repos/${initRepoCfg.repository}`) - .replyWithError(new Error('getRepo()')); + .replyWithError(httpMock.error('getRepo()')); await initFakePlatform(scope); await expect(gitea.initRepo(initRepoCfg)).rejects.toThrow('getRepo()'); }); diff --git a/lib/modules/platform/gitlab/index.spec.ts b/lib/modules/platform/gitlab/index.spec.ts index 47d42edf0b0f38..9cd159689e2eca 100644 --- a/lib/modules/platform/gitlab/index.spec.ts +++ b/lib/modules/platform/gitlab/index.spec.ts @@ -1554,7 +1554,7 @@ describe('modules/platform/gitlab/index', () => { httpMock .scope(gitlabApiHost) .get('/api/v4/users?username=someuser') - .reply(304, []) + .reply(200, []) .get('/api/v4/users?username=someotheruser') .reply(200, [{ id: 124 }]) .put('/api/v4/projects/undefined/merge_requests/42?assignee_ids[]=124') diff --git a/lib/util/http/github.spec.ts b/lib/util/http/github.spec.ts index fe9566c365029f..7223400b9ba493 100644 --- a/lib/util/http/github.spec.ts +++ b/lib/util/http/github.spec.ts @@ -333,7 +333,10 @@ describe('util/http/github', () => { async function failWithError(error: string | Record) { const url = '/some-url'; - httpMock.scope(githubApiHost).get(url).replyWithError(error); + httpMock + .scope(githubApiHost) + .get(url) + .replyWithError(httpMock.error(error)); await githubApi.getJsonUnchecked(url); } diff --git a/lib/util/http/gitlab.spec.ts b/lib/util/http/gitlab.spec.ts index 8f2f38d83e237e..9b0b9c6d88eb98 100644 --- a/lib/util/http/gitlab.spec.ts +++ b/lib/util/http/gitlab.spec.ts @@ -138,7 +138,7 @@ describe('util/http/gitlab', () => { httpMock .scope(gitlabApiHost) .get('/api/v4/some-url') - .replyWithError({ code: 'EAI_AGAIN' }); + .replyWithError(httpMock.error({ code: 'EAI_AGAIN' })); await expect(gitlabApi.get('some-url')).rejects.toThrow( EXTERNAL_HOST_ERROR, ); diff --git a/lib/util/http/index.spec.ts b/lib/util/http/index.spec.ts index 7ffa5caaa4684c..8af2746c61ee03 100644 --- a/lib/util/http/index.spec.ts +++ b/lib/util/http/index.spec.ts @@ -155,10 +155,12 @@ describe('util/http/index', () => { }); it('headJson', async () => { - httpMock.scope(baseUrl).head('/').reply(200, {}); + httpMock.scope(baseUrl).head('/').reply(200, undefined, { + 'content-type': 'application/json', + }); expect(await http.headJson('http://renovate.com', { baseUrl })).toEqual({ authorization: false, - body: {}, + body: '', headers: { 'content-type': 'application/json', }, diff --git a/lib/util/merge-confidence/index.spec.ts b/lib/util/merge-confidence/index.spec.ts index 7d7c72f8da219c..b93753fa9b1e98 100644 --- a/lib/util/merge-confidence/index.spec.ts +++ b/lib/util/merge-confidence/index.spec.ts @@ -414,7 +414,7 @@ describe('util/merge-confidence/index', () => { httpMock .scope(apiBaseUrl) .get(`/api/mc/availability`) - .replyWithError({ code: 'ECONNRESET' }); + .replyWithError(httpMock.error({ code: 'ECONNRESET' })); await expect( initMergeConfidence({ mergeConfidenceEndpoint: apiBaseUrl }), diff --git a/package.json b/package.json index 822bccde28231a..ca0020e2dcb2bb 100644 --- a/package.json +++ b/package.json @@ -331,7 +331,7 @@ "lint-staged": "15.4.3", "markdownlint-cli2": "0.17.2", "memfs": "4.17.0", - "nock": "13.5.6", + "nock": "14.0.1", "npm-run-all2": "7.0.2", "nyc": "17.1.0", "rimraf": "6.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6e8c95dd23f471..b053ffc95e8951 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -555,8 +555,8 @@ importers: specifier: 4.17.0 version: 4.17.0 nock: - specifier: 13.5.6 - version: 13.5.6 + specifier: 14.0.1 + version: 14.0.1 npm-run-all2: specifier: 7.0.2 version: 7.0.2 @@ -1358,6 +1358,10 @@ packages: os: [darwin, linux, win32] hasBin: true + '@mswjs/interceptors@0.37.6': + resolution: {integrity: sha512-wK+5pLK5XFmgtH3aQ2YVvA3HohS3xqV/OxuVOdNx9Wpnz7VE/fnC+e1A7ln6LFYeck7gOJ/dsZV6OLplOtAJ2w==} + engines: {node: '>=18'} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1437,6 +1441,15 @@ packages: '@one-ini/wasm@0.2.0': resolution: {integrity: sha512-n+L/BvrwKUn7q5O3wHGo+CJZAqfewh38+37sk+eBzv/39lM9pPgPRd4sOZRvSRzo0ukLxzyXso4WlGj2oKZ5hA==} + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + + '@open-draft/logger@0.3.0': + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + + '@open-draft/until@2.1.0': + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + '@openpgp/web-stream-tools@0.1.3': resolution: {integrity: sha512-mT/ds43cH6c+AO5RFpxs+LkACr7KjC3/dZWHrP6KPrWJu4uJ/XJ+p7telaoYiqUfdjiiIvdNSOfhezW9fkmboQ==} engines: {node: '>= 18.0.0'} @@ -4190,6 +4203,9 @@ packages: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} + is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + is-number-object@1.1.1: resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} @@ -5055,9 +5071,9 @@ packages: nise@6.1.1: resolution: {integrity: sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==} - nock@13.5.6: - resolution: {integrity: sha512-o2zOYiCpzRqSzPj0Zt/dQ/DqZeYoaQ7TUonc/xUPjCGl9WeHpNbxgVvOquXYAaJzI0M9BXV3HTzG0p8IUAbBTQ==} - engines: {node: '>= 10.13'} + nock@14.0.1: + resolution: {integrity: sha512-IJN4O9pturuRdn60NjQ7YkFt6Rwei7ZKaOwb1tvUIIqTgeD0SDDAX3vrqZD4wcXczeEy/AsUXxpGpP/yHqV7xg==} + engines: {node: '>=18.20.0 <20 || >=20.12.1'} node-abi@3.74.0: resolution: {integrity: sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==} @@ -5276,6 +5292,9 @@ packages: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} + outvariant@1.4.3: + resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + own-keys@1.0.1: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} @@ -6036,6 +6055,9 @@ packages: stream-combiner2@1.1.1: resolution: {integrity: sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==} + strict-event-emitter@0.5.1: + resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} + string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -8187,6 +8209,15 @@ snapshots: '@ls-lint/ls-lint@2.2.3': {} + '@mswjs/interceptors@0.37.6': + dependencies: + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.3 + strict-event-emitter: 0.5.1 + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -8282,6 +8313,15 @@ snapshots: '@one-ini/wasm@0.2.0': {} + '@open-draft/deferred-promise@2.2.0': {} + + '@open-draft/logger@0.3.0': + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.3 + + '@open-draft/until@2.1.0': {} + '@openpgp/web-stream-tools@0.1.3(typescript@5.7.3)': optionalDependencies: typescript: 5.7.3 @@ -11494,6 +11534,8 @@ snapshots: is-map@2.0.3: {} + is-node-process@1.2.0: {} + is-number-object@1.1.1: dependencies: call-bound: 1.0.3 @@ -12715,13 +12757,11 @@ snapshots: just-extend: 6.2.0 path-to-regexp: 8.2.0 - nock@13.5.6: + nock@14.0.1: dependencies: - debug: 4.4.0 + '@mswjs/interceptors': 0.37.6 json-stringify-safe: 5.0.1 propagate: 2.0.1 - transitivePeerDependencies: - - supports-color node-abi@3.74.0: dependencies: @@ -12932,6 +12972,8 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 + outvariant@1.4.3: {} + own-keys@1.0.1: dependencies: get-intrinsic: 1.3.0 @@ -13810,6 +13852,8 @@ snapshots: duplexer2: 0.1.4 readable-stream: 2.3.8 + strict-event-emitter@0.5.1: {} + string-argv@0.3.2: {} string-length@4.0.2: diff --git a/test/http-mock.ts b/test/http-mock.ts index a2ced5325a109a..ce695dd0aecdb1 100644 --- a/test/http-mock.ts +++ b/test/http-mock.ts @@ -1,5 +1,6 @@ import fs from 'node:fs'; import type { Url } from 'node:url'; +import is from '@sindresorhus/is'; import { codeBlock } from 'common-tags'; // eslint-disable-next-line no-restricted-imports import nock from 'nock'; @@ -264,3 +265,10 @@ afterAll(() => { afterEach(() => { clear(); }); + +export function error(props: string | Record = {}): Error { + if (is.string(props)) { + return new Error(props); + } + return Object.assign(new Error(), props); +}