From f223fc8fd8cd941b8610ed5d5ae67dbffd1c8c4d Mon Sep 17 00:00:00 2001 From: Pierrick Wauquier Date: Tue, 3 Mar 2020 18:36:51 +0100 Subject: [PATCH] fix(publisher-electron-release-server): throw an exception for 4xx/5xx HTTP status codes (#1538) --- .../electron-release-server/package.json | 4 ++- .../src/PublisherERS.ts | 17 +++++++++-- .../test/PublisherERS_spec.ts | 29 +++++++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 packages/publisher/electron-release-server/test/PublisherERS_spec.ts diff --git a/packages/publisher/electron-release-server/package.json b/packages/publisher/electron-release-server/package.json index 20f6827402..dcc1c65d51 100644 --- a/packages/publisher/electron-release-server/package.json +++ b/packages/publisher/electron-release-server/package.json @@ -9,7 +9,9 @@ "typings": "dist/PublisherERS.d.ts", "devDependencies": { "chai": "4.2.0", - "mocha": "^7.1.0" + "mocha": "^7.1.0", + "proxyquire": "^2.1.3", + "fetch-mock": "^9.0.0" }, "engines": { "node": ">= 10.0.0" diff --git a/packages/publisher/electron-release-server/src/PublisherERS.ts b/packages/publisher/electron-release-server/src/PublisherERS.ts index ef83401dbd..3a267c4ab2 100644 --- a/packages/publisher/electron-release-server/src/PublisherERS.ts +++ b/packages/publisher/electron-release-server/src/PublisherERS.ts @@ -3,7 +3,7 @@ import { asyncOra } from '@electron-forge/async-ora'; import { ForgePlatform, ForgeArch } from '@electron-forge/shared-types'; import debug from 'debug'; -import fetch from 'node-fetch'; +import fetch, { RequestInfo, RequestInit, Response } from 'node-fetch'; import FormData from 'form-data'; import fs from 'fs-extra'; import path from 'path'; @@ -17,6 +17,17 @@ interface ERSVersion { assets: { name: string; }[]; } +const fetchAndCheckStatus = async ( + url: RequestInfo, + init?: RequestInit, +): Promise => { + const result = await fetch(url, init); + if (result.ok) { // res.status >= 200 && res.status < 300 + return result; + } + throw new Error(`ERS publish failed with status code: ${result.status} (${result.url})`); +}; + export const ersPlatform = (platform: ForgePlatform, arch: ForgeArch) => { switch (platform) { case 'darwin': @@ -44,7 +55,7 @@ export default class PublisherERS extends PublisherBase { const api = (apiPath: string) => `${config.baseUrl}/${apiPath}`; - const { token } = await (await fetch(api('api/auth/login'), { + const { token } = await (await fetchAndCheckStatus(api('api/auth/login'), { method: 'POST', body: JSON.stringify({ username: config.username, @@ -56,7 +67,7 @@ export default class PublisherERS extends PublisherBase { })).json(); // eslint-disable-next-line max-len - const authFetch = (apiPath: string, options?: any) => fetch(api(apiPath), { ...options || {}, headers: { ...(options || {}).headers, Authorization: `Bearer ${token}` } }); + const authFetch = (apiPath: string, options?: any) => fetchAndCheckStatus(api(apiPath), { ...options || {}, headers: { ...(options || {}).headers, Authorization: `Bearer ${token}` } }); const versions: ERSVersion[] = await (await authFetch('api/version')).json(); diff --git a/packages/publisher/electron-release-server/test/PublisherERS_spec.ts b/packages/publisher/electron-release-server/test/PublisherERS_spec.ts new file mode 100644 index 0000000000..570ca734c9 --- /dev/null +++ b/packages/publisher/electron-release-server/test/PublisherERS_spec.ts @@ -0,0 +1,29 @@ +import { expect } from 'chai'; +import { ForgeConfig } from '@electron-forge/shared-types'; +import fetchMock from 'fetch-mock'; +import proxyquire from 'proxyquire'; + +describe('PublisherERS', () => { + let fetch: typeof fetchMock; + beforeEach(() => { + fetch = fetchMock.sandbox(); + }); + it('fail if the server returns 4xx', async () => { + fetch.mock('begin:http://example.com', { body: {}, status: 400 }); + const PublisherERS = proxyquire.noCallThru().load('../src/PublisherERS', { + 'node-fetch': fetch, + }).default; + + + const publisher = new PublisherERS({ + baseUrl: 'http://example.com', + username: 'test', + password: 'test', + }); + return expect(publisher.publish({ makeResults: [], dir: '', forgeConfig: {} as ForgeConfig })).to.eventually.be.rejectedWith('ERS publish failed with status code: 400 (http://example.com/api/auth/login)'); + }); + + afterEach(() => { + fetch.restore(); + }); +});