diff --git a/.changeset/gentle-kangaroos-agree.md b/.changeset/gentle-kangaroos-agree.md new file mode 100644 index 0000000000..791b313103 --- /dev/null +++ b/.changeset/gentle-kangaroos-agree.md @@ -0,0 +1,5 @@ +--- +"pnpm": patch +--- + +Fail with a meaningful error when the audit endpoint doesn't exist [#5200](https://github.com/pnpm/pnpm/issues/5200). diff --git a/.changeset/tough-eyes-study.md b/.changeset/tough-eyes-study.md new file mode 100644 index 0000000000..3899669c90 --- /dev/null +++ b/.changeset/tough-eyes-study.md @@ -0,0 +1,8 @@ +--- +"@pnpm/audit": patch +"@pnpm/plugin-commands-audit": patch +--- + +- Add new Error type: AuditEndpointNotExistsError +- On AuditUrl returns 404, AuditEndpointNotExistsError will throw +- When audit handler catches AuditEndpointNotExistsError, the command will return to avoid execute further codes diff --git a/packages/audit/src/index.ts b/packages/audit/src/index.ts index bc32ed7086..603e2cb857 100644 --- a/packages/audit/src/index.ts +++ b/packages/audit/src/index.ts @@ -35,6 +35,11 @@ export default async function audit ( retry: opts.retry, timeout: opts.timeout, }) + + if (res.status === 404) { + throw new AuditEndpointNotExistsError(auditUrl) + } + if (res.status !== 200) { throw new PnpmError('AUDIT_BAD_RESPONSE', `The audit endpoint (at ${auditUrl}) responded with ${res.status}: ${await res.text()}`) } @@ -53,3 +58,16 @@ function getAuthHeaders ( } return headers } + +export class AuditEndpointNotExistsError extends PnpmError { + constructor (endpoint: string) { + const message = `The audit endpoint (at ${endpoint}) is doesn't exist.` + super( + 'AUDIT_ENDPOINT_NOT_EXISTS', + message, + { + hint: 'This issue is probably because you are using a private npm registry and that endpoint doesn\'t have an implementation of audit.', + } + ) + } +} diff --git a/packages/plugin-commands-audit/src/audit.ts b/packages/plugin-commands-audit/src/audit.ts index 2edceaf982..48729957bc 100644 --- a/packages/plugin-commands-audit/src/audit.ts +++ b/packages/plugin-commands-audit/src/audit.ts @@ -171,6 +171,8 @@ export async function handler ( output: err.message, } } + + throw err } if (opts.fix) { const newOverrides = await fix(opts.dir, auditReport) diff --git a/packages/plugin-commands-audit/test/index.ts b/packages/plugin-commands-audit/test/index.ts index 1b42641008..6e27ed1c4e 100644 --- a/packages/plugin-commands-audit/test/index.ts +++ b/packages/plugin-commands-audit/test/index.ts @@ -1,5 +1,6 @@ import path from 'path' import { audit } from '@pnpm/plugin-commands-audit' +import { AuditEndpointNotExistsError } from '@pnpm/audit' import nock from 'nock' import stripAnsi from 'strip-ansi' import * as responses from './utils/responses' @@ -154,3 +155,20 @@ test('audit sends authToken if alwaysAuth is true', async () => { expect(stripAnsi(output)).toBe('No known vulnerabilities found\n') expect(exitCode).toBe(0) }) + +test('audit endpoint does not exist', async () => { + nock(registries.default) + .post('/-/npm/v1/security/audits') + .reply(404, {}) + + await expect(audit.handler({ + dir: path.join(__dirname, 'fixtures/has-vulnerabilities'), + dev: true, + fetchRetries: 0, + ignoreRegistryErrors: false, + production: false, + userConfig: {}, + rawConfig, + registries, + })).rejects.toThrow(AuditEndpointNotExistsError) +})