From de8d5eef37f53e577f538a7983235fd4f0dd4410 Mon Sep 17 00:00:00 2001 From: Janne Savolainen Date: Wed, 25 May 2022 08:29:00 +0300 Subject: [PATCH] Make higher order function for logging errors support asynchronous rejecting with non error instance Signed-off-by: Janne Savolainen --- .../with-error-logging.injectable.ts | 13 ++++--- .../with-error-logging.test.ts | 34 +++++++++++++++++-- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/common/utils/with-error-logging/with-error-logging.injectable.ts b/src/common/utils/with-error-logging/with-error-logging.injectable.ts index d019d5d392..5b9f3d5b21 100644 --- a/src/common/utils/with-error-logging/with-error-logging.injectable.ts +++ b/src/common/utils/with-error-logging/with-error-logging.injectable.ts @@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import loggerInjectable from "../../logger.injectable"; export type WithErrorLoggingFor = ( - getErrorMessage: (error: Error) => string + getErrorMessage: (error: unknown) => string ) => any>( toBeDecorated: T ) => (...args: Parameters) => ReturnType; @@ -24,14 +24,19 @@ const withErrorLoggingInjectable = getInjectable({ const returnValue = toBeDecorated(...args); if (isPromise(returnValue)) { - returnValue.catch((e: Error) => { - logger.error(getErrorMessage(e as Error), e); + returnValue.catch((e) => { + const errorMessage = getErrorMessage(e); + + logger.error(errorMessage, e); }); } return returnValue; } catch (e) { - logger.error(getErrorMessage(e as Error), e); + const errorMessage = getErrorMessage(e); + + logger.error(errorMessage, e); + throw e; } }; diff --git a/src/common/utils/with-error-logging/with-error-logging.test.ts b/src/common/utils/with-error-logging/with-error-logging.test.ts index cc4348f3bf..533374d9ad 100644 --- a/src/common/utils/with-error-logging/with-error-logging.test.ts +++ b/src/common/utils/with-error-logging/with-error-logging.test.ts @@ -33,7 +33,7 @@ describe("with-error-logging", () => { decorated = pipeline( toBeDecorated, - withErrorLoggingFor((error: Error) => `some-error-message-for-${error.message}`), + withErrorLoggingFor((error: any) => `some-error-message-for-${error.message}`), ); }); @@ -133,7 +133,11 @@ describe("with-error-logging", () => { decorated = pipeline( toBeDecorated, - withErrorLoggingFor((error: Error) => `some-error-message-for-${error.message}`), + + withErrorLoggingFor( + (error: any) => + `some-error-message-for-${error.message || error.someProperty}`, + ), ); }); @@ -158,7 +162,7 @@ describe("with-error-logging", () => { expect(promiseStatus.fulfilled).toBe(false); }); - describe("when call rejects", () => { + describe("when call rejects with error instance", () => { let error: Error; beforeEach(async () => { @@ -179,6 +183,30 @@ describe("with-error-logging", () => { }); }); + describe("when call rejects with something else than error instance", () => { + let error: unknown; + + beforeEach(async () => { + try { + await toBeDecorated.reject({ someProperty: "some-rejection" }); + await returnValuePromise; + } catch (e) { + error = e; + } + }); + + it("logs the rejection", () => { + expect(loggerStub.error).toHaveBeenCalledWith( + "some-error-message-for-some-rejection", + error, + ); + }); + + it("rejects", () => { + return expect(() => returnValuePromise).rejects.toEqual({ someProperty: "some-rejection" }); + }); + }); + describe("when call resolves with value", () => { beforeEach(async () => { await toBeDecorated.resolve(42);