mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Introduce a way to make intentional orphan promises uniform, controllable and deliberate
Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>
This commit is contained in:
parent
ebda9424bb
commit
2cd18c7245
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type { AsyncFnMock } from "@async-fn/jest";
|
||||
import asyncFn from "@async-fn/jest";
|
||||
import { getDiForUnitTesting } from "../../../main/getDiForUnitTesting";
|
||||
import loggerInjectable from "../../logger.injectable";
|
||||
import type { Logger } from "../../logger";
|
||||
import withOrphanPromiseInjectable from "./with-orphan-promise";
|
||||
|
||||
describe("with orphan promise, when called", () => {
|
||||
let toBeDecorated: AsyncFnMock<(arg1: string, arg2: string) => Promise<string>>;
|
||||
let actual: void;
|
||||
let loggerStub: Logger;
|
||||
|
||||
beforeEach(() => {
|
||||
const di = getDiForUnitTesting({ doGeneralOverrides: true });
|
||||
|
||||
di.register(withOrphanPromiseInjectable);
|
||||
|
||||
loggerStub = { error: jest.fn() } as unknown as Logger;
|
||||
|
||||
di.override(loggerInjectable, () => loggerStub);
|
||||
|
||||
const withOrphanPromise = di.inject(withOrphanPromiseInjectable);
|
||||
|
||||
toBeDecorated = asyncFn();
|
||||
|
||||
const decorated = withOrphanPromise(toBeDecorated);
|
||||
|
||||
actual = decorated("some-argument", "some-other-argument");
|
||||
});
|
||||
|
||||
it("calls decorated with arguments", () => {
|
||||
expect(toBeDecorated).toHaveBeenCalledWith("some-argument", "some-other-argument");
|
||||
});
|
||||
|
||||
it("given promise returned by decorated has not been fulfilled yet, already returns nothing", () => {
|
||||
expect(actual).toBeUndefined();
|
||||
});
|
||||
|
||||
it("when decorated function resolves, nothing happens", async () => {
|
||||
await toBeDecorated.resolve("irrelevant");
|
||||
// Note: there is no expect, test is here only for documentation.
|
||||
});
|
||||
|
||||
describe("when decorated function rejects", () => {
|
||||
beforeEach(async () => {
|
||||
await toBeDecorated.reject("some-error");
|
||||
});
|
||||
|
||||
it("logs the rejection", () => {
|
||||
expect(loggerStub.error).toHaveBeenCalledWith("Orphan promise rejection encountered", "some-error");
|
||||
});
|
||||
|
||||
it("nothing else happens", () => {
|
||||
// Note: there is no expect, test is here only for documentation.
|
||||
});
|
||||
});
|
||||
});
|
||||
29
src/common/utils/with-orphan-promise/with-orphan-promise.ts
Normal file
29
src/common/utils/with-orphan-promise/with-orphan-promise.ts
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import withErrorLoggingInjectable from "../with-error-logging/with-error-logging.injectable";
|
||||
import { withErrorSuppression } from "../with-error-suppression/with-error-suppression";
|
||||
import { pipeline } from "@ogre-tools/fp";
|
||||
|
||||
const withOrphanPromiseInjectable = getInjectable({
|
||||
id: "with-orphan-promise",
|
||||
|
||||
instantiate: (di) => {
|
||||
const withErrorLoggingFor = di.inject(withErrorLoggingInjectable);
|
||||
|
||||
return <T extends (...args: any[]) => Promise<any>>(toBeDecorated: T) =>
|
||||
(...args: Parameters<T>): void => {
|
||||
const decorated = pipeline(
|
||||
toBeDecorated,
|
||||
withErrorLoggingFor(() => "Orphan promise rejection encountered"),
|
||||
withErrorSuppression,
|
||||
);
|
||||
|
||||
decorated(...args);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default withOrphanPromiseInjectable;
|
||||
Loading…
Reference in New Issue
Block a user