diff --git a/frontend/src/lib/components/apps/components/display/table/AppTable.svelte b/frontend/src/lib/components/apps/components/display/table/AppTable.svelte
index 93c8745930..bd0a9f0073 100644
--- a/frontend/src/lib/components/apps/components/display/table/AppTable.svelte
+++ b/frontend/src/lib/components/apps/components/display/table/AppTable.svelte
@@ -355,11 +355,13 @@
/>
{:else if result != undefined}
-
- The result should be an array of objects. Received:
-
- {JSON.stringify(result)}
-
-
+
+
+ The result should be an array of objects. Received:
+
+ {JSON.stringify(result, null, 4)}
+
+
+
{/if}
diff --git a/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte b/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte
index 1a70f531f5..0551487774 100644
--- a/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte
+++ b/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte
@@ -244,6 +244,8 @@
}
async function setResult(res: any) {
+ const hasRes = res !== undefined && res !== null
+
if (transformer) {
$worldStore.newOutput(id, 'raw', res)
res = await eval_like(
@@ -255,7 +257,18 @@
$componentControl,
$worldStore
)
+
+ if (hasRes && res === undefined) {
+ res = {
+ error: {
+ name: 'TransformerError',
+ message: 'An error occured in the transformer',
+ stack: 'Transformer returned undefined'
+ }
+ }
+ }
}
+
outputs.result?.set(res)
result = res
diff --git a/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte b/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte
index 56b4826f5b..c0bfe301c8 100644
--- a/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte
+++ b/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte
@@ -18,7 +18,6 @@
import DisplayResult from '$lib/components/DisplayResult.svelte'
import Dropdown from '$lib/components/Dropdown.svelte'
import FlowProgressBar from '$lib/components/flows/FlowProgressBar.svelte'
- import { idMutex } from '$lib/components/flows/flowStateUtils'
import FlowStatusViewer from '$lib/components/FlowStatusViewer.svelte'
import JobArgs from '$lib/components/JobArgs.svelte'
import LogViewer from '$lib/components/LogViewer.svelte'
@@ -43,12 +42,9 @@
Eye,
Laptop2,
Loader2,
- MoreVertical,
Pencil,
- Redo,
SlidersHorizontal,
Smartphone,
- Undo,
X
} from 'lucide-svelte'
import { getContext } from 'svelte'
diff --git a/frontend/src/lib/components/apps/editor/ComponentHeader.svelte b/frontend/src/lib/components/apps/editor/ComponentHeader.svelte
index 6dec1d4a1d..57b42a26d8 100644
--- a/frontend/src/lib/components/apps/editor/ComponentHeader.svelte
+++ b/frontend/src/lib/components/apps/editor/ComponentHeader.svelte
@@ -7,6 +7,7 @@
import { Alert, Button } from '$lib/components/common'
import type { AppComponent } from './component'
import { twMerge } from 'tailwind-merge'
+ import { getErrorFromLatestResult } from './appUtils'
export let component: AppComponent
export let selected: boolean
@@ -15,9 +16,9 @@
const dispatch = createEventDispatcher()
- const { errorByComponent, openDebugRun } = getContext('AppViewerContext')
+ const { errorByComponent, openDebugRun, jobs } = getContext('AppViewerContext')
- $: error = Object.values($errorByComponent).find((e) => e.componentId === component.id)
+ $: error = getErrorFromLatestResult(component.id, $errorByComponent, $jobs)
function openDebugRuns() {
if ($openDebugRun) {
@@ -84,7 +85,7 @@
{/if}
{#if error}
- {@const json = JSON.parse(JSON.stringify(error.error))}
+ {@const json = JSON.parse(JSON.stringify(error))}
-
{json?.stack ?? ''}
-
+
+ {json?.stack ?? ''}
+
diff --git a/frontend/src/lib/components/apps/editor/appUtils.ts b/frontend/src/lib/components/apps/editor/appUtils.ts
index a6d72f9ef8..cc0b33d6c2 100644
--- a/frontend/src/lib/components/apps/editor/appUtils.ts
+++ b/frontend/src/lib/components/apps/editor/appUtils.ts
@@ -568,3 +568,56 @@ export function recursivelyFilterKeyInJSON(
})
return filteredJSON
}
+
+export function clearErrorByComponentId(
+ id: string,
+ errorByComponent: Record<
+ string,
+ {
+ error: string
+ componentId: string
+ }
+ >
+) {
+ return Object.entries(errorByComponent).reduce((acc, [key, value]) => {
+ if (value.componentId !== id) {
+ acc[key] = value
+ }
+ return acc
+ }, {})
+}
+
+export function clearJobsByComponentId(
+ id: string,
+ jobs: {
+ job: string
+ component: string
+ }[]
+) {
+ return jobs.filter((job) => job.component !== id)
+}
+
+// Returns the error message for the latest job for a component if an error occurred, otherwise undefined
+export function getErrorFromLatestResult(
+ id: string,
+ errorByComponent: Record<
+ string, // job id
+ {
+ error: string
+ componentId: string
+ }
+ >,
+ jobs: {
+ job: string
+ component: string
+ }[]
+) {
+ // find last jobId for component id
+ const lastJob = jobs.find((job) => job.component === id)
+
+ if (lastJob?.job && errorByComponent[lastJob.job]) {
+ return errorByComponent[lastJob.job].error
+ } else {
+ return undefined
+ }
+}
diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/ComponentPanel.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/ComponentPanel.svelte
index 1b050626f7..cf8c46ee55 100644
--- a/frontend/src/lib/components/apps/editor/settingsPanel/ComponentPanel.svelte
+++ b/frontend/src/lib/components/apps/editor/settingsPanel/ComponentPanel.svelte
@@ -17,10 +17,10 @@
import AlignmentEditor from './AlignmentEditor.svelte'
import RunnableInputEditor from './inputEditor/RunnableInputEditor.svelte'
import TemplateEditor from '$lib/components/TemplateEditor.svelte'
- import { ccomponents, components, type AppComponent } from '../component'
+ import { ccomponents, type AppComponent } from '../component'
import CssProperty from '../componentsPanel/CssProperty.svelte'
import GridTab from './GridTab.svelte'
- import { deleteGridItem } from '../appUtils'
+ import { clearErrorByComponentId, clearJobsByComponentId, deleteGridItem } from '../appUtils'
import GridPane from './GridPane.svelte'
import { slide } from 'svelte/transition'
import { push } from '$lib/history'
@@ -35,8 +35,17 @@
let editor: TemplateEditor | undefined = undefined
- const { app, runnableComponents, selectedComponent, worldStore, focusedGrid, stateId, state } =
- getContext('AppViewerContext')
+ const {
+ app,
+ runnableComponents,
+ selectedComponent,
+ worldStore,
+ focusedGrid,
+ stateId,
+ state,
+ errorByComponent,
+ jobs
+ } = getContext('AppViewerContext')
const { history, ontextfocus } = getContext('AppEditorContext')
@@ -44,6 +53,10 @@
function removeGridElement() {
push(history, $app)
+
+ $errorByComponent = clearErrorByComponentId(component.id, $errorByComponent)
+ $jobs = clearJobsByComponentId(component.id, $jobs)
+
$selectedComponent = undefined
$focusedGrid = undefined
if (componentSettings?.item && !noGrid) {
diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/TableActions.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/TableActions.svelte
index bdcd8d6b5e..2ab3621006 100644
--- a/frontend/src/lib/components/apps/editor/settingsPanel/TableActions.svelte
+++ b/frontend/src/lib/components/apps/editor/settingsPanel/TableActions.svelte
@@ -7,7 +7,11 @@
import { getContext } from 'svelte'
import { Icon } from 'svelte-awesome'
import type { AppViewerContext, BaseAppComponent } from '../../types'
- import { appComponentFromType } from '../appUtils'
+ import {
+ appComponentFromType,
+ clearErrorByComponentId,
+ clearJobsByComponentId
+ } from '../appUtils'
import type { ButtonComponent } from '../component'
import PanelSection from './common/PanelSection.svelte'
import TableActionLabel from './TableActionLabel.svelte'
@@ -15,7 +19,8 @@
export let components: (BaseAppComponent & ButtonComponent)[]
export let id: string
- const { selectedComponent, app } = getContext('AppViewerContext')
+ const { selectedComponent, app, errorByComponent, jobs } =
+ getContext('AppViewerContext')
function addComponent() {
const actionId = getNextId(components.map((x) => x.id.split('_')[1]))
@@ -30,6 +35,10 @@
function deleteComponent(cid: string) {
components = components.filter((x) => x.id !== cid)
+
+ $errorByComponent = clearErrorByComponentId(cid, $errorByComponent)
+ $jobs = clearJobsByComponentId(cid, $jobs)
+
$selectedComponent = id
$app = $app
}