fix(frontend): Fix AppTable error display + clear errors when removing a component + properly detect that latest component run had an error (#1322)

This commit is contained in:
Faton Ramadani
2023-03-23 20:54:02 +01:00
committed by GitHub
parent 30b8e474df
commit c15bc8a7bf
7 changed files with 109 additions and 22 deletions
@@ -355,11 +355,13 @@
/>
</div>
{:else if result != undefined}
<Alert title="Parsing issues" type="error" size="xs">
The result should be an array of objects. Received:
<pre class="overflow-auto">
{JSON.stringify(result)}
</pre>
</Alert>
<div class="flex flex-col h-full w-full overflow-auto">
<Alert title="Parsing issues" type="error" size="xs" class="h-full w-full ">
The result should be an array of objects. Received:
<pre class="w-full bg-white p-2 rounded-md">
{JSON.stringify(result, null, 4)}
</pre>
</Alert>
</div>
{/if}
</RunnableWrapper>
@@ -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
@@ -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'
@@ -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>('AppViewerContext')
const { errorByComponent, openDebugRun, jobs } = getContext<AppViewerContext>('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))}
<span
title="Error"
class={classNames(
@@ -99,9 +100,9 @@
<Alert type="error" title={`${json?.name}: ${json?.message}`}>
<div class="flex flex-col gap-2">
<div>
<pre class=" whitespace-pre-wrap text-gray-900 bg-white border w-full p-4 text-xs"
>{json?.stack ?? ''}
</pre>
<pre class=" whitespace-pre-wrap text-gray-900 bg-white border w-full p-4 text-xs">
{json?.stack ?? ''}
</pre>
</div>
<Button color="red" variant="border" on:click={openDebugRuns}>Open Debug Runs</Button>
</div>
@@ -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
}
}
@@ -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>('AppViewerContext')
const {
app,
runnableComponents,
selectedComponent,
worldStore,
focusedGrid,
stateId,
state,
errorByComponent,
jobs
} = getContext<AppViewerContext>('AppViewerContext')
const { history, ontextfocus } = getContext<AppEditorContext>('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) {
@@ -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>('AppViewerContext')
const { selectedComponent, app, errorByComponent, jobs } =
getContext<AppViewerContext>('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
}