From 73469c4833fff23fe527b0053439e7544ee2166c Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Fri, 13 Jan 2023 11:07:16 -0500 Subject: [PATCH] Improve error handling and reporting in setup-lens-proxy Signed-off-by: Sebastian Malton --- .../runnables/setup-lens-proxy.injectable.ts | 106 ++++++++++-------- 1 file changed, 59 insertions(+), 47 deletions(-) diff --git a/src/main/start-main-application/runnables/setup-lens-proxy.injectable.ts b/src/main/start-main-application/runnables/setup-lens-proxy.injectable.ts index e40a0ea9c4..7305fc7fa9 100644 --- a/src/main/start-main-application/runnables/setup-lens-proxy.injectable.ts +++ b/src/main/start-main-application/runnables/setup-lens-proxy.injectable.ts @@ -12,68 +12,80 @@ import { beforeApplicationIsLoadingInjectionToken } from "../runnable-tokens/bef import buildVersionInjectable from "../../vars/build-version/build-version.injectable"; import initializeBuildVersionInjectable from "../../vars/build-version/init.injectable"; import lensFetchInjectable from "../../../common/fetch/lens-fetch.injectable"; +import initAuthHeaderStateInjectable from "../../../features/auth-header/main/init-state.injectable"; +import { hasTypedProperty, isObject, isString, json } from "../../../common/utils"; const setupLensProxyInjectable = getInjectable({ id: "setup-lens-proxy", - instantiate: (di) => { - const lensProxy = di.inject(lensProxyInjectable); - const exitApp = di.inject(exitAppInjectable); - const logger = di.inject(loggerInjectable); - const isWindows = di.inject(isWindowsInjectable); - const showErrorPopup = di.inject(showErrorPopupInjectable); - const buildVersion = di.inject(buildVersionInjectable); - const lensFetch = di.inject(lensFetchInjectable); + instantiate: (di) => ({ + id: "setup-lens-proxy", + run: async () => { + const lensProxy = di.inject(lensProxyInjectable); + const exitApp = di.inject(exitAppInjectable); + const logger = di.inject(loggerInjectable); + const isWindows = di.inject(isWindowsInjectable); + const showErrorPopup = di.inject(showErrorPopupInjectable); + const buildVersion = di.inject(buildVersionInjectable); + const lensFetch = di.inject(lensFetchInjectable); - return { - id: "setup-lens-proxy", - run: async () => { - try { - logger.info("🔌 Starting LensProxy"); - await lensProxy.listen(); // lensProxy.port available - } catch (error) { - const message = error instanceof Error ? error.message : "unknown error"; + const showProxyError = (error: string) => { + const hostsPath = isWindows + ? "C:\\windows\\system32\\drivers\\etc\\hosts" + : "/etc/hosts"; + const message = [ + `Failed connection test: ${error}`, + "Check to make sure that no other versions of Lens are running", + `Check ${hostsPath} to make sure that it is clean and that the localhost loopback is at the top and set to 127.0.0.1`, + "If you have HTTP_PROXY or http_proxy set in your environment, make sure that the localhost and the ipv4 loopback address 127.0.0.1 are added to the NO_PROXY environment variable.", + ].join("\n\n"); - showErrorPopup("Lens Error", `Could not start proxy: ${message}`); + logger.error(`🛑 LensProxy: failed connection test: ${error}`); + showErrorPopup("Lens Proxy Error", message); + exitApp(); + }; - return exitApp(); - } + try { + logger.info("🔌 Starting LensProxy"); + await lensProxy.listen(); // lensProxy.port available + } catch (error) { + const message = error instanceof Error ? error.message : "unknown error"; - // test proxy connection - try { - logger.info("🔎 Testing LensProxy connection ..."); - const versionResponse = await lensFetch("/version"); + showErrorPopup("Lens Error", `Could not start proxy: ${message}`); + exitApp(); - const { version: versionFromProxy } = await versionResponse.json() as { version: string }; + return; + } - if (buildVersion.get() !== versionFromProxy) { - logger.error("Proxy server responded with invalid response"); + logger.info("🔎 Testing LensProxy connection ..."); + const versionResponse = await lensFetch("/version"); - return exitApp(); - } + if (versionResponse.status !== 200) { + return showProxyError(`failed to GET /version: ${versionResponse.statusText}`); + } - logger.info("⚡ LensProxy connection OK"); - } catch (error) { - logger.error(`🛑 LensProxy: failed connection test: ${error}`); + const body = await versionResponse.text(); + const { isOk, value, error } = json.parse(body); - const hostsPath = isWindows - ? "C:\\windows\\system32\\drivers\\etc\\hosts" - : "/etc/hosts"; - const message = [ - `Failed connection test: ${error}`, - "Check to make sure that no other versions of Lens are running", - `Check ${hostsPath} to make sure that it is clean and that the localhost loopback is at the top and set to 127.0.0.1`, - "If you have HTTP_PROXY or http_proxy set in your environment, make sure that the localhost and the ipv4 loopback address 127.0.0.1 are added to the NO_PROXY environment variable.", - ]; + if (!isOk) { + return showProxyError(`failed to parse response body ${error.cause} for "${error.text}"`); + } - showErrorPopup("Lens Proxy Error", message.join("\n\n")); + if (!isObject(value) || !hasTypedProperty(value, "version", isString)) { + return showProxyError(`invalid data returned: "${body}"`); + } - return exitApp(); - } - }, - runAfter: di.inject(initializeBuildVersionInjectable), - }; - }, + if (buildVersion.get() !== value.version) { + return showProxyError("Proxy server response with unexpeced version"); + } + + logger.info("⚡ LensProxy connection OK"); + }, + runAfter: [ + di.inject(initializeBuildVersionInjectable), + di.inject(initAuthHeaderStateInjectable), + ], + }), injectionToken: beforeApplicationIsLoadingInjectionToken, });