diff --git a/src/headless/config/types.ts b/src/headless/config/types.ts index 371518ea2..71805867e 100644 --- a/src/headless/config/types.ts +++ b/src/headless/config/types.ts @@ -30,15 +30,18 @@ export function toUpdateConfigContent( /** * Helper to convert InstallationConfigContent to ConfigContent - * Throws error if required fields are missing + * Returns result object with either data or error */ -export function toCreateConfigContent( - config: InstallationConfigContent, -): ConfigContent { +export function toCreateConfigContent(config: InstallationConfigContent): { + data?: ConfigContent; + error?: Error; +} { if (!isValidCreateConfig(config)) { - throw new Error("Config must have a provider field for creation"); + return { + error: new Error("Config must have a provider field for creation"), + }; } - return config; + return { data: config }; } export type { InstallationConfigContent }; diff --git a/src/headless/installation/useCreateInstallation.ts b/src/headless/installation/useCreateInstallation.ts index 34f58a7cb..14a2d76fc 100644 --- a/src/headless/installation/useCreateInstallation.ts +++ b/src/headless/installation/useCreateInstallation.ts @@ -50,7 +50,9 @@ export function useCreateInstallation() { onSettled?: () => void; }) => { if (installation) { - const error = new Error("Installation already created. Try updating instead."); + const error = new Error( + "Installation already created. Try updating instead.", + ); onError?.(error); onSettled?.(); return; @@ -61,6 +63,17 @@ export function useCreateInstallation() { onSettled?.(); return; } + + // Validate config before creating installation + const configResult = toCreateConfigContent(config); + if (configResult.error || !configResult.data) { + onError?.( + configResult.error || new Error("Invalid configuration data"), + ); + onSettled?.(); + return; + } + // assemble create installation requests from providers const createInstallationRequest: CreateInstallationOperationRequest = { projectIdOrName, @@ -69,7 +82,7 @@ export function useCreateInstallation() { groupRef, connectionId: connection?.id, config: { - content: toCreateConfigContent(config), + content: configResult.data, }, }, }; diff --git a/src/hooks/mutation/useUpdateOauthConnectMutation.ts b/src/hooks/mutation/useUpdateOauthConnectMutation.ts index 1bfa23263..5a5c9c3c2 100644 --- a/src/hooks/mutation/useUpdateOauthConnectMutation.ts +++ b/src/hooks/mutation/useUpdateOauthConnectMutation.ts @@ -8,10 +8,14 @@ export const useUpdateOauthConnectMutation = () => { return useMutation({ mutationKey: ["updateOauthConnection"], mutationFn: async (request: OauthUpdateRequest) => { - const api = await getAPI(); + // Validate required fields before making API call if (!request.projectIdOrName || !request.connectionId) { - throw new Error("Project ID and connection ID are required"); + // Return rejected promise instead of throw to be more explicit + return Promise.reject( + new Error("Project ID and connection ID are required"), + ); } + const api = await getAPI(); return api.oAuthApi.oauthUpdate(request); }, onSuccess: () => {