Add winston formatting support for error causes (#6576)

* Add winston formatting support for error causes

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix failing to run built version

- Finally make logger fully injectable
- Simplify startMainApplication to only have runMany(Sync) invocations
  to fix time of use bugs related to logger

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Remove legacy type enforced ipc to fix tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix type error

Signed-off-by: Sebastian Malton <sebastian@malton.name>

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton authored and GitHub committed 2022-11-17 14:56:16 +02:00
1 parent a4d0451dec
commit 8dd1d1a8fa
28 files changed
+544 -506

No files matched your search

@@ -1,131 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { EventEmitter } from "events";
import { onCorrect, onceCorrect } from "../type-enforced-ipc";
describe("type enforced ipc tests", () => {
describe("onCorrect tests", () => {
it("should call the handler if the args are valid", () => {
let called = false;
const source = new EventEmitter();
const listener = () => called = true;
const verifier = (args: unknown[]): args is [] => true;
const channel = "foobar";
onCorrect({ source, listener, verifier, channel });
source.emit(channel);
expect(called).toBe(true);
});
it("should not call the handler if the args are not valid", () => {
let called = false;
const source = new EventEmitter();
const listener = () => called = true;
const verifier = (args: unknown[]): args is [] => false;
const channel = "foobar";
onCorrect({ source, listener, verifier, channel });
source.emit(channel);
expect(called).toBe(false);
});
it("should call the handler twice if the args are valid on two emits", () => {
let called = 0;
const source = new EventEmitter();
const listener = () => called += 1;
const verifier = (args: unknown[]): args is [] => true;
const channel = "foobar";
onCorrect({ source, listener, verifier, channel });
source.emit(channel);
source.emit(channel);
expect(called).toBe(2);
});
it("should call the handler twice if the args are [valid, invalid, valid]", () => {
let called = 0;
const source = new EventEmitter();
const listener = () => called += 1;
const results = [true, false, true];
const verifier = (args: unknown[]): args is [] => results.pop() ?? false;
const channel = "foobar";
onCorrect({ source, listener, verifier, channel });
source.emit(channel);
source.emit(channel);
source.emit(channel);
expect(called).toBe(2);
});
});
describe("onceCorrect tests", () => {
it("should call the handler if the args are valid", () => {
let called = false;
const source = new EventEmitter();
const listener = () => called = true;
const verifier = (args: unknown[]): args is [] => true;
const channel = "foobar";
onceCorrect({ source, listener, verifier, channel });
source.emit(channel);
expect(called).toBe(true);
});
it("should not call the handler if the args are not valid", () => {
let called = false;
const source = new EventEmitter();
const listener = () => called = true;
const verifier = (args: unknown[]): args is [] => false;
const channel = "foobar";
onceCorrect({ source, listener, verifier, channel });
source.emit(channel);
expect(called).toBe(false);
});
it("should call the handler only once even if args are valid multiple times", () => {
let called = 0;
const source = new EventEmitter();
const listener = () => called += 1;
const verifier = (args: unknown[]): args is [] => true;
const channel = "foobar";
onceCorrect({ source, listener, verifier, channel });
source.emit(channel);
source.emit(channel);
expect(called).toBe(1);
});
it("should call the handler on only the first valid set of args", () => {
let called = "";
let verifierCalled = 0;
const source = new EventEmitter();
const listener = (info: any, arg: string) => called = arg;
const verifier = (args: unknown[]): args is [string] => (++verifierCalled) % 3 === 0;
const channel = "foobar";
onceCorrect({ source, listener, verifier, channel });
source.emit(channel, {}, "a");
source.emit(channel, {}, "b");
source.emit(channel, {}, "c");
source.emit(channel, {}, "d");
source.emit(channel, {}, "e");
source.emit(channel, {}, "f");
source.emit(channel, {}, "g");
source.emit(channel, {}, "h");
source.emit(channel, {}, "i");
expect(called).toBe("c");
});
});
});
-1
View File
@@ -5,4 +5,3 @@
export * from "./ipc";
export * from "./invalid-kubeconfig";
export * from "./type-enforced-ipc";
-107
View File
@@ -1,107 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { EventEmitter } from "events";
import { ipcMain } from "electron";
import logger from "../../main/logger";
import type { Disposer } from "../utils";
import { ipcMainHandle } from "./ipc";
export type ListenerEvent<EM extends EventEmitter> = Parameters<Parameters<EM["on"]>[1]>[0];
export type ListVerifier<T extends any[]> = (args: unknown[]) => args is T;
export type Rest<T> = T extends [any, ...infer R] ? R : [];
/**
* Adds a listener to `source` that waits for the first IPC message with the correct
* argument data is sent.
* @param channel The channel to be listened on
* @param listener The function for the channel to be called if the args of the correct type
* @param verifier The function to be called to verify that the args are the correct type
*/
export function onceCorrect<
IPC extends EventEmitter,
Listener extends (event: ListenerEvent<IPC>, ...args: any[]) => any,
>({
source,
channel,
listener,
verifier,
}: {
source: IPC;
channel: string;
listener: Listener;
verifier: ListVerifier<Rest<Parameters<Listener>>>;
}): void {
function wrappedListener(event: ListenerEvent<IPC>, ...args: unknown[]): void {
if (verifier(args)) {
source.removeListener(channel, wrappedListener); // remove immediately
(async () => (listener(event, ...args)))() // might return a promise, or throw, or reject
.catch((error: any) => logger.error("[IPC]: channel once handler threw error", { channel, error }));
} else {
logger.error("[IPC]: channel was emitted with invalid data", { channel, args });
}
}
source.on(channel, wrappedListener);
}
/**
* Adds a listener to `source` that checks to verify the arguments before calling the handler.
* @param channel The channel to be listened on
* @param listener The function for the channel to be called if the args of the correct type
* @param verifier The function to be called to verify that the args are the correct type
*/
export function onCorrect<
IPC extends EventEmitter,
Listener extends (event: ListenerEvent<IPC>, ...args: any[]) => any,
>({
source,
channel,
listener,
verifier,
}: {
source: IPC;
channel: string;
listener: Listener;
verifier: ListVerifier<Rest<Parameters<Listener>>>;
}): Disposer {
function wrappedListener(event: ListenerEvent<IPC>, ...args: unknown[]) {
if (verifier(args)) {
(async () => (listener(event, ...args)))() // might return a promise, or throw, or reject
.catch(error => logger.error("[IPC]: channel on handler threw error", { channel, error }));
} else {
logger.error("[IPC]: channel was emitted with invalid data", { channel, args });
}
}
source.on(channel, wrappedListener);
return () => source.off(channel, wrappedListener);
}
export function handleCorrect<
Handler extends (event: Electron.IpcMainInvokeEvent, ...args: any[]) => any,
>({
channel,
handler,
verifier,
}: {
channel: string;
handler: Handler;
verifier: ListVerifier<Rest<Parameters<Handler>>>;
}): Disposer {
function wrappedHandler(event: Electron.IpcMainInvokeEvent, ...args: unknown[]): ReturnType<Handler> {
if (verifier(args)) {
return handler(event, ...args);
}
throw new TypeError(`Invalid args for invoke on channel: ${channel}`);
}
ipcMainHandle(channel, wrappedHandler);
return () => ipcMain.removeHandler(channel);
}