diff --git a/src/common/k8s-api/endpoints/resource-applier.api/request-patch.injectable.ts b/src/common/k8s-api/endpoints/resource-applier.api/request-patch.injectable.ts index 7290263a41..49271fb6d2 100644 --- a/src/common/k8s-api/endpoints/resource-applier.api/request-patch.injectable.ts +++ b/src/common/k8s-api/endpoints/resource-applier.api/request-patch.injectable.ts @@ -5,25 +5,44 @@ import { getInjectable } from "@ogre-tools/injectable"; import type { Patch } from "rfc6902"; import apiBaseInjectable from "../../api-base.injectable"; +import type { AsyncResult } from "../../../utils/async-result"; import type { KubeJsonApiData } from "../../kube-json-api"; -export type RequestKubeObjectPatch = (name: string, kind: string, ns: string | undefined, patch: Patch) => Promise; +export type RequestKubeObjectPatch = (name: string, kind: string, ns: string | undefined, patch: Patch) => Promise>; const requestKubeObjectPatchInjectable = getInjectable({ id: "request-kube-object-patch", instantiate: (di): RequestKubeObjectPatch => { const apiBase = di.inject(apiBaseInjectable); - return (name, kind, ns, patch) => ( - apiBase.patch("/stack", { + return async (name, kind, ns, patch) => { + const result = await apiBase.patch("/stack", { data: { name, kind, ns, patch, }, - }) - ); + }) as AsyncResult; + + if (!result.callWasSuccessful) { + return result; + } + + try { + const response = JSON.parse(result.response); + + return { + callWasSuccessful: true, + response, + }; + } catch (error) { + return { + callWasSuccessful: false, + error: String(error), + }; + } + }; }, }); diff --git a/src/common/k8s-api/endpoints/resource-applier.api/request-update.injectable.ts b/src/common/k8s-api/endpoints/resource-applier.api/request-update.injectable.ts index 7d996253ee..1891a779cf 100644 --- a/src/common/k8s-api/endpoints/resource-applier.api/request-update.injectable.ts +++ b/src/common/k8s-api/endpoints/resource-applier.api/request-update.injectable.ts @@ -4,16 +4,37 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import apiBaseInjectable from "../../api-base.injectable"; +import type { AsyncResult } from "../../../utils/async-result"; import type { KubeJsonApiData } from "../../kube-json-api"; -export type RequestKubeObjectCreation = (resourceDescriptor: string) => Promise; +export type RequestKubeObjectCreation = (resourceDescriptor: string) => Promise>; const requestKubeObjectCreationInjectable = getInjectable({ id: "request-kube-object-creation", instantiate: (di): RequestKubeObjectCreation => { const apiBase = di.inject(apiBaseInjectable); - return (data) => apiBase.post("/stack", { data }); + return async (data) => { + const result = await apiBase.post("/stack", { data }) as AsyncResult; + + if (!result.callWasSuccessful) { + return result; + } + + try { + const response = JSON.parse(result.response); + + return { + callWasSuccessful: true, + response, + }; + } catch (error) { + return { + callWasSuccessful: false, + error: String(error), + }; + } + }; }, }); diff --git a/src/common/k8s-api/kube-object.ts b/src/common/k8s-api/kube-object.ts index 24e34eff4b..53bc6defdf 100644 --- a/src/common/k8s-api/kube-object.ts +++ b/src/common/k8s-api/kube-object.ts @@ -645,8 +645,13 @@ export class KubeObject< } const requestKubeObjectPatch = asLegacyGlobalFunctionForExtensionApi(requestKubeObjectPatchInjectable); + const result = await requestKubeObjectPatch(this.getName(), this.kind, this.getNs(), patch); - return requestKubeObjectPatch(this.getName(), this.kind, this.getNs(), patch); + if (!result.callWasSuccessful) { + throw new Error(result.error); + } + + return result.response; } /** @@ -665,7 +670,13 @@ export class KubeObject< ...data, }); - return requestKubeObjectCreation(descriptor); + const result = await requestKubeObjectCreation(descriptor); + + if (!result.callWasSuccessful) { + throw new Error(result.error); + } + + return result.response; } /** diff --git a/src/common/logger.injectable.ts b/src/common/logger.injectable.ts index e1a085f199..8e9dd2a6a7 100644 --- a/src/common/logger.injectable.ts +++ b/src/common/logger.injectable.ts @@ -9,13 +9,23 @@ import { loggerTransportInjectionToken } from "./logger/transports"; const loggerInjectable = getInjectable({ id: "logger", - instantiate: (di): Logger => createLogger({ - format: format.combine( - format.splat(), - format.simple(), - ), - transports: di.injectMany(loggerTransportInjectionToken), - }), + instantiate: (di): Logger => { + const baseLogger = createLogger({ + format: format.combine( + format.splat(), + format.simple(), + ), + transports: di.injectMany(loggerTransportInjectionToken), + }); + + return { + debug: (message, ...data) => baseLogger.debug(message, ...data), + info: (message, ...data) => baseLogger.info(message, ...data), + warn: (message, ...data) => baseLogger.warn(message, ...data), + error: (message, ...data) => baseLogger.error(message, ...data), + silly: (message, ...data) => baseLogger.silly(message, ...data), + }; + }, }); export default loggerInjectable; diff --git a/src/common/logger.ts b/src/common/logger.ts index 948404a6b9..0b460a48ff 100644 --- a/src/common/logger.ts +++ b/src/common/logger.ts @@ -17,4 +17,6 @@ export interface Logger { /** * @deprecated use `di.inject(loggerInjectable)` instead */ -export default asLegacyGlobalForExtensionApi(loggerInjectable); +const logger = asLegacyGlobalForExtensionApi(loggerInjectable); + +export default logger; diff --git a/src/renderer/components/dock/create-resource/view.tsx b/src/renderer/components/dock/create-resource/view.tsx index d84a823259..00221a7b32 100644 --- a/src/renderer/components/dock/create-resource/view.tsx +++ b/src/renderer/components/dock/create-resource/view.tsx @@ -13,8 +13,8 @@ import { observer } from "mobx-react"; import type { CreateResourceTabStore } from "./store"; import { EditorPanel } from "../editor-panel"; import { InfoPanel } from "../info-panel"; -import { Notifications } from "../../notifications"; -import logger from "../../../../common/logger"; +import type { ShowNotification } from "../../notifications"; +import type { Logger } from "../../../../common/logger"; import type { ApiManager } from "../../../../common/k8s-api/api-manager"; import { isObject, prevDefault } from "../../../utils"; import { withInjectables } from "@ogre-tools/injectable-react"; @@ -29,6 +29,10 @@ import getDetailsUrlInjectable from "../../kube-detail-params/get-details-url.in import navigateInjectable from "../../../navigation/navigate.injectable"; import type { RequestKubeObjectCreation } from "../../../../common/k8s-api/endpoints/resource-applier.api/request-update.injectable"; import requestKubeObjectCreationInjectable from "../../../../common/k8s-api/endpoints/resource-applier.api/request-update.injectable"; +import loggerInjectable from "../../../../common/logger.injectable"; +import type { ShowCheckedErrorNotification } from "../../notifications/show-checked-error.injectable"; +import showSuccessNotificationInjectable from "../../notifications/show-success-notification.injectable"; +import showCheckedErrorNotificationInjectable from "../../notifications/show-checked-error.injectable"; export interface CreateResourceProps { tabId: string; @@ -38,9 +42,12 @@ interface Dependencies { createResourceTemplates: IComputedValue[]>; createResourceTabStore: CreateResourceTabStore; apiManager: ApiManager; + logger: Logger; navigate: Navigate; getDetailsUrl: GetDetailsUrl; requestKubeObjectCreation: RequestKubeObjectCreation; + showSuccessNotification: ShowNotification; + showCheckedErrorNotification: ShowCheckedErrorNotification; } @observer @@ -81,34 +88,38 @@ class NonInjectedCreateResource extends React.Component { - try { - const data = await requestKubeObjectCreation(dump(resource)); - const { kind, apiVersion, metadata: { name, namespace }} = data; + const result = await requestKubeObjectCreation(dump(resource)); - const showDetails = () => { - const resourceLink = apiManager.lookupApiLink({ kind, apiVersion, name, namespace }); + if (!result.callWasSuccessful) { + this.props.logger.warn("Failed to create resource", { resource }, result.error); + this.props.showCheckedErrorNotification(result.error, "Unknown error occured while creating resources"); - navigate(getDetailsUrl(resourceLink)); - close(); - }; - - const close = Notifications.ok( -

- {kind} - {" "} - - {name} - - {" successfully created."} -

, - ); - } catch (error) { - Notifications.checkedError(error, "Unknown error occured while creating resources"); + return; } + + const { kind, apiVersion, metadata: { name, namespace }} = result.response; + + const close = this.props.showSuccessNotification(( +

+ {kind} + {" "} + { + const resourceLink = apiManager.lookupApiLink({ kind, apiVersion, name, namespace }); + + navigate(getDetailsUrl(resourceLink)); + close(); + })} + > + {name} + + {" successfully created."} +

+ )); }); await Promise.allSettled(creatingResources); @@ -168,8 +179,11 @@ export const CreateResource = withInjectables createResourceTabStore: di.inject(createResourceTabStoreInjectable), createResourceTemplates: await di.inject(createResourceTemplatesInjectable), apiManager: di.inject(apiManagerInjectable), + logger: di.inject(loggerInjectable), getDetailsUrl: di.inject(getDetailsUrlInjectable), navigate: di.inject(navigateInjectable), requestKubeObjectCreation: di.inject(requestKubeObjectCreationInjectable), + showSuccessNotification: di.inject(showSuccessNotificationInjectable), + showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable), }), });