From a03a4911dbe2dbeb698a5d4d4218580e5ebbc27e Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Sun, 10 Nov 2019 14:56:57 +0200 Subject: [PATCH] fix: better message on integrity checksum error --- packages/supi/test/lockfile.ts | 2 +- .../tarball-fetcher/src/createDownloader.ts | 35 +++++++++++++++++-- packages/tarball-fetcher/test/download.ts | 6 ++-- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/packages/supi/test/lockfile.ts b/packages/supi/test/lockfile.ts index 1610596dab..962f4db100 100644 --- a/packages/supi/test/lockfile.ts +++ b/packages/supi/test/lockfile.ts @@ -148,7 +148,7 @@ test('fail when shasum from lockfile does not match with the actual one', async }, await testDefaults({}, {}, { fetchRetries: 0 })) t.fail('installation should have failed') } catch (err) { - t.equal(err.code, 'EINTEGRITY') + t.equal(err.code, 'ERR_PNPM_TARBALL_INTEGRITY') } }) diff --git a/packages/tarball-fetcher/src/createDownloader.ts b/packages/tarball-fetcher/src/createDownloader.ts index 3eb4dcf5a4..2650e68c44 100644 --- a/packages/tarball-fetcher/src/createDownloader.ts +++ b/packages/tarball-fetcher/src/createDownloader.ts @@ -29,6 +29,29 @@ class TarballFetchError extends PnpmError { } } +class TarballIntegrityError extends PnpmError { + public readonly found: string + public readonly expected: string + public readonly algorithm: string + public readonly sri: string + public readonly url: string + + constructor (opts: { + found: string, + expected: string, + algorithm: string, + sri: string, + url: string, + }) { + super('TARBALL_INTEGRITY', `Got unexpected checksum for "${opts.url}". Wanted "${opts.expected}". Got "${opts.found}".`) + this.found = opts.found + this.expected = opts.expected + this.algorithm = opts.algorithm + this.sri = opts.sri + this.url = opts.url + } +} + export interface HttpResponse { body: string } @@ -173,7 +196,7 @@ export default ( const tempLocation = pathTemp(opts.unpackTo) const ignore = gotOpts.fsIsCaseSensitive ? opts.ignore : createIgnorer(url, opts.ignore) Promise.all([ - opts.integrity && safeCheckStream(res.body, opts.integrity) || true, + opts.integrity && safeCheckStream(res.body, opts.integrity, url) || true, unpackStream.local(res.body, tempLocation, { generateIntegrity: opts.generatePackageIntegrity, ignore, @@ -241,12 +264,18 @@ function createIgnorer (tarballUrl: string, ignore?: (filename: string) => boole } } -async function safeCheckStream (stream: any, integrity: string): Promise { // tslint:disable-line:no-any +async function safeCheckStream (stream: any, integrity: string, url: string): Promise { // tslint:disable-line:no-any try { await ssri.checkStream(stream, integrity) return true } catch (err) { - return err + return new TarballIntegrityError({ + algorithm: err['algorithm'], + expected: err['expected'], + found: err['found'], + sri: err['sri'], + url, + }) } } diff --git a/packages/tarball-fetcher/test/download.ts b/packages/tarball-fetcher/test/download.ts index 418df0d869..7f2700f7c8 100644 --- a/packages/tarball-fetcher/test/download.ts +++ b/packages/tarball-fetcher/test/download.ts @@ -256,9 +256,9 @@ test('fail when integrity check fails two times in a row', async t => { }) t.fail('should have failed') } catch (err) { - t.equal(err.message, 'sha1-HssnaJydJVE+rbyZFKc/VAi+enY= integrity checksum failed when using sha1: ' + - 'wanted sha1-HssnaJydJVE+rbyZFKc/VAi+enY= but got sha512-VuFL1iPaIxJK/k3gTxStIkc6+wSiDwlLdnCWNZyapsVLobu/0onvGOZolASZpfBFiDJYrOIGiDzgLIULTW61Vg== sha1-ACjKMFA7S6uRFXSDFfH4aT+4B4Y=. (1194 bytes)') - t.equal(err['code'], 'EINTEGRITY') + t.equal(err.message, 'Got unexpected checksum for "http://example.com/foo.tgz". Wanted "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=". ' + + 'Got "sha512-VuFL1iPaIxJK/k3gTxStIkc6+wSiDwlLdnCWNZyapsVLobu/0onvGOZolASZpfBFiDJYrOIGiDzgLIULTW61Vg== sha1-ACjKMFA7S6uRFXSDFfH4aT+4B4Y=".') + t.equal(err['code'], 'ERR_PNPM_TARBALL_INTEGRITY') t.equal(err['resource'], 'http://example.com/foo.tgz') t.equal(err['attempts'], 2)