Skip to content

Commit 18bb804

Browse files
committed
fix(notifications): throw notification on runtime errors, move predeploy checks to update in deploy modal
1 parent c749229 commit 18bb804

File tree

3 files changed

+52
-35
lines changed

3 files changed

+52
-35
lines changed

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/deploy-modal.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
import { getBaseUrl } from '@/lib/core/utils/urls'
2020
import { getInputFormatExample as getInputFormatExampleUtil } from '@/lib/workflows/operations/deployment-utils'
2121
import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider'
22+
import { runPreDeployChecks } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/hooks/use-predeploy-checks'
2223
import { CreateApiKeyModal } from '@/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/api-keys/components'
2324
import { startsWithUuid } from '@/executor/constants'
2425
import { useA2AAgentByWorkflow } from '@/hooks/queries/a2a/agents'
@@ -38,6 +39,7 @@ import { useWorkspaceSettings } from '@/hooks/queries/workspace'
3839
import { usePermissionConfig } from '@/hooks/use-permission-config'
3940
import { useSettingsModalStore } from '@/stores/modals/settings/store'
4041
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
42+
import { mergeSubblockState } from '@/stores/workflows/utils'
4143
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
4244
import type { WorkflowState } from '@/stores/workflows/workflow/types'
4345
import { A2aDeploy } from './components/a2a/a2a'
@@ -335,6 +337,20 @@ export function DeployModal({
335337
setDeployError(null)
336338
setDeployWarnings([])
337339

340+
const { blocks, edges, loops, parallels } = useWorkflowStore.getState()
341+
const liveBlocks = mergeSubblockState(blocks, workflowId)
342+
const checkResult = runPreDeployChecks({
343+
blocks: liveBlocks,
344+
edges,
345+
loops,
346+
parallels,
347+
workflowId,
348+
})
349+
if (!checkResult.passed) {
350+
setDeployError(checkResult.error || 'Pre-deploy validation failed')
351+
return
352+
}
353+
338354
try {
339355
const result = await deployMutation.mutateAsync({ workflowId, deployChatEnabled: false })
340356
if (result.warnings && result.warnings.length > 0) {

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/hooks/use-deployment.ts

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@ import { useCallback, useState } from 'react'
22
import { createLogger } from '@sim/logger'
33
import { useNotificationStore } from '@/stores/notifications'
44
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
5-
import { mergeSubblockState } from '@/stores/workflows/utils'
6-
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
7-
import { runPreDeployChecks } from './use-predeploy-checks'
85

96
const logger = createLogger('useDeployment')
107

@@ -25,36 +22,16 @@ export function useDeployment({
2522
const [isDeploying, setIsDeploying] = useState(false)
2623
const setDeploymentStatus = useWorkflowRegistry((state) => state.setDeploymentStatus)
2724
const addNotification = useNotificationStore((state) => state.addNotification)
28-
const blocks = useWorkflowStore((state) => state.blocks)
29-
const edges = useWorkflowStore((state) => state.edges)
30-
const loops = useWorkflowStore((state) => state.loops)
31-
const parallels = useWorkflowStore((state) => state.parallels)
3225

3326
/**
3427
* Handle deploy button click
3528
* First deploy: calls API to deploy, then opens modal on success
36-
* Redeploy: validates client-side, then opens modal if valid
29+
* Already deployed: opens modal directly (validation happens on Update in modal)
3730
*/
3831
const handleDeployClick = useCallback(async () => {
3932
if (!workflowId) return { success: false, shouldOpenModal: false }
4033

4134
if (isDeployed) {
42-
const liveBlocks = mergeSubblockState(blocks, workflowId)
43-
const checkResult = runPreDeployChecks({
44-
blocks: liveBlocks,
45-
edges,
46-
loops,
47-
parallels,
48-
workflowId,
49-
})
50-
if (!checkResult.passed) {
51-
addNotification({
52-
level: 'error',
53-
message: checkResult.error || 'Pre-deploy validation failed',
54-
workflowId,
55-
})
56-
return { success: false, shouldOpenModal: false }
57-
}
5835
return { success: true, shouldOpenModal: true }
5936
}
6037

@@ -101,17 +78,7 @@ export function useDeployment({
10178
} finally {
10279
setIsDeploying(false)
10380
}
104-
}, [
105-
workflowId,
106-
isDeployed,
107-
blocks,
108-
edges,
109-
loops,
110-
parallels,
111-
refetchDeployedState,
112-
setDeploymentStatus,
113-
addNotification,
114-
])
81+
}, [workflowId, isDeployed, refetchDeployedState, setDeploymentStatus, addNotification])
11582

11683
return {
11784
isDeploying,

apps/sim/stores/terminal/console/store.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,40 @@ export const useTerminalConsoleStore = create<ConsoleStore>()(
376376

377377
return { entries: updatedEntries }
378378
})
379+
380+
if (typeof update === 'object' && update.error) {
381+
const settings = getQueryClient().getQueryData<GeneralSettings>(
382+
generalSettingsKeys.settings()
383+
)
384+
const isErrorNotificationsEnabled = settings?.errorNotificationsEnabled ?? true
385+
386+
if (isErrorNotificationsEnabled) {
387+
try {
388+
const matchingEntry = get().entries.find(
389+
(e) => e.blockId === blockId && e.executionId === executionId
390+
)
391+
const errorMessage = String(update.error)
392+
const blockName = matchingEntry?.blockName || 'Unknown Block'
393+
const displayMessage = `${blockName}: ${errorMessage}`
394+
const copilotMessage = `${errorMessage}\n\nError in ${blockName}.\n\nPlease fix this.`
395+
396+
useNotificationStore.getState().addNotification({
397+
level: 'error',
398+
message: displayMessage,
399+
workflowId: matchingEntry?.workflowId,
400+
action: {
401+
type: 'copilot',
402+
message: copilotMessage,
403+
},
404+
})
405+
} catch (notificationError) {
406+
logger.error('Failed to create block error notification', {
407+
blockId,
408+
error: notificationError,
409+
})
410+
}
411+
}
412+
}
379413
},
380414

381415
cancelRunningEntries: (workflowId: string) => {

0 commit comments

Comments
 (0)