diff --git a/package-lock.json b/package-lock.json index b4f6d92..8f506a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -415,6 +415,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/xml/-/xml-1.0.5.tgz", "integrity": "sha512-h3PVM7waRi2UeoaY2BhpLGvettU/3vfCbsjXMV/9Ex5WjvIy82J8Qfp1xiPxM4kTSOLdFFpjRwQ7YY7XJeKBvg==", + "dev": true, "requires": { "@types/node": "*" } @@ -2089,6 +2090,11 @@ "lru-cache": "^6.0.0" } }, + "http-status-codes": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.1.4.tgz", + "integrity": "sha512-MZVIsLKGVOVE1KEnldppe6Ij+vmemMuApDfjhVSLzyYP+td0bREEYyAoIw9yFePoBXManCuBqmiNP5FqJS5Xkg==" + }, "husky": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.0.tgz", @@ -3568,7 +3574,8 @@ "typescript": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.2.tgz", - "integrity": "sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==" + "integrity": "sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==", + "dev": true }, "universalify": { "version": "1.0.0", @@ -3722,7 +3729,8 @@ "xml": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", - "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=" + "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=", + "dev": true }, "xtend": { "version": "4.0.2", diff --git a/package.json b/package.json index aca3b8b..a7d7229 100644 --- a/package.json +++ b/package.json @@ -31,10 +31,11 @@ }, "homepage": "https://github.com/MapColonies/node-osm-api#readme", "dependencies": { - "@types/node": "^14.14.9", - "axios": "^0.21.0" + "axios": "^0.21.0", + "http-status-codes": "^2.1.4" }, "devDependencies": { + "@types/node": "^14.14.9", "@commitlint/config-conventional": "^11.0.0", "@map-colonies/eslint-config": "^1.1.0", "@types/chai": "^4.2.14", diff --git a/src/api/v6/index.ts b/src/api/v6/index.ts index 3a62ef8..245a02e 100644 --- a/src/api/v6/index.ts +++ b/src/api/v6/index.ts @@ -1,7 +1,7 @@ -import axios, { AxiosInstance, AxiosResponse } from 'axios'; -import { IResponse } from '../../lib/response-handler'; +import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios'; +import StatusCodes from 'http-status-codes'; import { createChangesetEndPoint } from '../../lib/endpoints'; -import HttpErrorHandler from '../../lib/http-error-handler'; +import { Unauthorized, BADXml, InternalServerError } from '../../lib/error-handler'; class Apiv6 { private readonly httpClient: AxiosInstance; @@ -9,16 +9,27 @@ class Apiv6 { this.httpClient = axios.create({ baseURL: baseUrl, auth: { username, password } }); } - public async createChangeset(data: string): Promise> { + public async createChangeset(data: string): Promise { let res: AxiosResponse; try { res = await this.httpClient.put(createChangesetEndPoint, data); - } + } catch (e) { - throw new HttpErrorHandler(e); + const axiosError = e as AxiosError; + + if (!axiosError.response) { + throw new InternalServerError(e); + } + if (axiosError.response.status === StatusCodes.BAD_REQUEST) { + throw new BADXml(axiosError); + } else if (axiosError.response.status === StatusCodes.UNAUTHORIZED) { + throw new Unauthorized(axiosError); + } else { + throw new InternalServerError(e); + } } - const { status, data: changeSetId } = res; - return { status, data: changeSetId }; + const { data: changeSetId } = res; + return changeSetId; } } diff --git a/src/lib/error-handler.ts b/src/lib/error-handler.ts new file mode 100644 index 0000000..7834fb4 --- /dev/null +++ b/src/lib/error-handler.ts @@ -0,0 +1,29 @@ +import { AxiosError } from "axios"; + +class HttpErrorHandler extends Error { + public constructor(error: AxiosError) { + super(error.response?.data); + Object.setPrototypeOf(this, HttpErrorHandler.prototype); + } +} + +export class Unauthorized extends HttpErrorHandler { + public constructor(error: AxiosError) { + super(error); + Object.setPrototypeOf(this, Unauthorized.prototype); + } +} + +export class BADXml extends HttpErrorHandler { + public constructor(error: AxiosError) { + super(error); + Object.setPrototypeOf(this, BADXml.prototype); + } +} + +export class InternalServerError extends HttpErrorHandler { + public constructor(error: AxiosError) { + super(error); + Object.setPrototypeOf(this, InternalServerError.prototype); + } +} \ No newline at end of file diff --git a/src/lib/http-error-handler.ts b/src/lib/http-error-handler.ts deleted file mode 100644 index 09dc2cb..0000000 --- a/src/lib/http-error-handler.ts +++ /dev/null @@ -1,15 +0,0 @@ -export interface MyError extends Error { - response: { data: string, status: number }; -} - -class HttpErrorHandler extends Error { - private readonly status: number - - public constructor(error: MyError) { - super(error.response.data); - this.status = error.response.status; - Object.setPrototypeOf(this, HttpErrorHandler.prototype); - } -} - -export default HttpErrorHandler; \ No newline at end of file diff --git a/src/lib/response-handler.ts b/src/lib/response-handler.ts deleted file mode 100644 index 8ef8028..0000000 --- a/src/lib/response-handler.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface IResponse { - status: number, - data: T -} \ No newline at end of file diff --git a/tests/unit/unit.test.ts b/tests/unit/unit.test.ts index 72ae84d..3080167 100644 --- a/tests/unit/unit.test.ts +++ b/tests/unit/unit.test.ts @@ -20,11 +20,7 @@ describe('apiv6', function () { const xmlData = createChangesetXml("test-generator", "test-user"); const res = await apiv6.createChangeset(xmlData); - expect(res).to.be.a('object') - .with.property('status') - .and.to.be.equal(200); - expect(res).to.have.property('data') - .and.to.be.equal(12); + expect(res).to.be.equal(12); }); }); describe('with unregisterd user', function () { @@ -38,11 +34,10 @@ describe('apiv6', function () { try { await apiv6.createChangeset(xmlData); } catch (e) { + console.log(e); expect(e).to.be.a('Error') .with.property('message') .and.to.be.equal('Couldn\'t authenticate you'); - expect(e).to.have.property('status') - .and.to.be.equal(401); } }); });