Skip to content

Commit 3bdc279

Browse files
authored
fix(workflows): surface workflow import failures (#7768)
* fix(workflows): show errors when workflow imports fail * fix(workflows): clarify invalid import file errors
1 parent 9294beb commit 3bdc279

1 file changed

Lines changed: 29 additions & 10 deletions

File tree

apps/sim/app/workspace/[workspaceId]/w/hooks/use-import-workflow.ts

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { useCallback, useRef, useState } from 'react'
2+
import { toast } from '@sim/emcn'
23
import { createLogger } from '@sim/logger'
4+
import { getErrorMessage } from '@sim/utils/errors'
35
import { useQueryClient } from '@tanstack/react-query'
46
import { useRouter } from 'next/navigation'
57
import { usePostHog } from 'posthog-js/react'
@@ -34,9 +36,9 @@ interface UseImportWorkflowProps {
3436
*/
3537
export function useImportWorkflow({ workspaceId }: UseImportWorkflowProps) {
3638
const router = useRouter()
37-
const createWorkflowMutation = useCreateWorkflow()
39+
const { mutateAsync: createWorkflow } = useCreateWorkflow()
3840
const queryClient = useQueryClient()
39-
const createFolderMutation = useCreateFolder()
41+
const { mutateAsync: createFolder } = useCreateFolder()
4042
const clearDiff = useWorkflowDiffStore((state) => state.clearDiff)
4143
const posthog = usePostHog()
4244
const posthogRef = useRef(posthog)
@@ -56,7 +58,7 @@ export function useImportWorkflow({ workspaceId }: UseImportWorkflowProps) {
5658
folderId,
5759
sortOrder,
5860
createWorkflow: async ({ name, description, workspaceId, folderId, sortOrder }) =>
59-
createWorkflowMutation.mutateAsync({
61+
createWorkflow({
6062
name,
6163
description,
6264
workspaceId,
@@ -66,9 +68,13 @@ export function useImportWorkflow({ workspaceId }: UseImportWorkflowProps) {
6668
}),
6769
})
6870

69-
return result?.workflowId ?? null
71+
if (!result) {
72+
throw new Error('The file does not contain valid workflow JSON.')
73+
}
74+
75+
return result.workflowId
7076
},
71-
[clearDiff, createWorkflowMutation, workspaceId]
77+
[clearDiff, createWorkflow, workspaceId]
7278
)
7379

7480
/**
@@ -89,10 +95,16 @@ export function useImportWorkflow({ workspaceId }: UseImportWorkflowProps) {
8995

9096
if (hasZip && fileArray.length === 1) {
9197
const zipFile = fileArray[0]
92-
const { workflows: extractedWorkflows, metadata } = await extractWorkflowsFromZip(zipFile)
98+
const { workflows: extractedWorkflows, metadata } = await extractWorkflowsFromZip(
99+
zipFile
100+
).catch((error: unknown) => {
101+
throw new Error('Failed to import ZIP file. Check that it is a valid ZIP archive.', {
102+
cause: error,
103+
})
104+
})
93105

94106
const folderName = metadata?.workspaceName || zipFile.name.replace(/\.zip$/i, '')
95-
const importFolder = await createFolderMutation.mutateAsync({
107+
const importFolder = await createFolder({
96108
name: folderName,
97109
workspaceId,
98110
})
@@ -131,7 +143,7 @@ export function useImportWorkflow({ workspaceId }: UseImportWorkflowProps) {
131143
parentId = await createFolderRecursive(foldersById.get(folder.parentId)!)
132144
}
133145

134-
const newFolder = await createFolderMutation.mutateAsync({
146+
const newFolder = await createFolder({
135147
name: folder.name,
136148
workspaceId,
137149
parentId,
@@ -163,7 +175,7 @@ export function useImportWorkflow({ workspaceId }: UseImportWorkflowProps) {
163175
const folderNameForSegment = workflow.folderPath[i]
164176

165177
if (!folderMap.has(pathSegment)) {
166-
const subFolder = await createFolderMutation.mutateAsync({
178+
const subFolder = await createFolder({
167179
name: folderNameForSegment,
168180
workspaceId,
169181
parentId,
@@ -187,6 +199,9 @@ export function useImportWorkflow({ workspaceId }: UseImportWorkflowProps) {
187199
if (workflowId) importedWorkflowIds.push(workflowId)
188200
} catch (error) {
189201
logger.error(`Failed to import ${workflow.name}:`, error)
202+
toast.error(`Failed to import ${workflow.name}`, {
203+
description: getErrorMessage(error, 'Workflow import failed'),
204+
})
190205
}
191206
}
192207
} else if (jsonFiles.length > 0) {
@@ -198,6 +213,9 @@ export function useImportWorkflow({ workspaceId }: UseImportWorkflowProps) {
198213
if (workflowId) importedWorkflowIds.push(workflowId)
199214
} catch (error) {
200215
logger.error(`Failed to import ${workflow.name}:`, error)
216+
toast.error(`Failed to import ${workflow.name}`, {
217+
description: getErrorMessage(error, 'Workflow import failed'),
218+
})
201219
}
202220
}
203221
}
@@ -219,6 +237,7 @@ export function useImportWorkflow({ workspaceId }: UseImportWorkflowProps) {
219237
}
220238
} catch (error) {
221239
logger.error('Failed to import workflows:', error)
240+
toast.error(getErrorMessage(error, 'Failed to import workflows'))
222241
} finally {
223242
setIsImporting(false)
224243

@@ -227,7 +246,7 @@ export function useImportWorkflow({ workspaceId }: UseImportWorkflowProps) {
227246
}
228247
}
229248
},
230-
[importSingleWorkflow, workspaceId, router, createFolderMutation, queryClient]
249+
[importSingleWorkflow, workspaceId, router, createFolder, queryClient]
231250
)
232251

233252
return {

0 commit comments

Comments
 (0)