diff --git a/package-lock.json b/package-lock.json index 29fddd6..9f7c69f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "o.js", - "version": "2.0.0-rc1", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "o.js", - "version": "2.0.0-rc1", + "version": "2.0.0", "license": "MIT", "dependencies": { "cross-fetch": "^3.0.6", diff --git a/src/OHandler.ts b/src/OHandler.ts index fc86b24..522bf50 100644 --- a/src/OHandler.ts +++ b/src/OHandler.ts @@ -59,7 +59,6 @@ export class OHandler { const json = await Promise.all( response.map(async (res) => { if (res.status >= 400) { - this.config.onError(this, res); throw res; } else if (res.ok && res.json) { try { @@ -76,6 +75,7 @@ export class OHandler { ); return json.length > 1 ? json : json[0]; } catch (ex) { + this.config.onError(this, ex); throw ex; } finally { this.requests = []; @@ -117,6 +117,7 @@ export class OHandler { const data = await batch.fetch(url); return data; } catch (ex) { + this.config.onError(this, ex); throw ex; } finally { this.requests = []; diff --git a/src/o.spec.ts b/src/o.spec.ts index 321cde3..f526c08 100644 --- a/src/o.spec.ts +++ b/src/o.spec.ts @@ -396,6 +396,50 @@ describe("GET request", () => { }); }); +describe("Error handling", () => { + let oHandler; + let onError; + + beforeEach(() => { + onError = jest.fn(); + oHandler = o("https://services.odata.org/V4/TripPinServiceRW/", { onError }); + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + test.each([ + "query", + "fetch", + "batch", + ])("Callback onError is called in %s when network call fails", async (method) => { + // given + const resource = "People"; + const fetchError = new TypeError("Failed to fetch"); + + jest + .spyOn(window, "fetch") + .mockRejectedValue(fetchError); + + // when / expect + await expect(async () => await oHandler.get(resource)[method]()).rejects.toBe(fetchError); + expect(onError).toHaveBeenCalledTimes(1); + expect(onError).toHaveBeenCalledWith(oHandler, fetchError); + }); + + // Unlike fetch and batch methods, query is the only one that analyze the response status code and throws an error + // if the status code is not 2xx. + test("Callback onError is called in query when response code is 404", async () => { + // given + const resource = "UnknownResource"; + // when / expect + await expect(async () => await oHandler.get(resource).query()).rejects.toMatchObject({ status: 404 }); + expect(onError).toHaveBeenCalledTimes(1); + expect(onError).toHaveBeenCalledWith(oHandler, expect.objectContaining({ status: 404 })); + }); +}); + describe("Create, Update and Delete request", () => { let oHandler;