Ensure exceptions in the executor are handled properly (#239)
Right now, if the executor throws a KCLError (e.g. for "variable name is not defined" errors), they aren't being caught by the .catch or the try/catch block in asyncWrap. This PR fixes it. Co-authored-by: Kurt Hutten Irev-Dev <k.hutten@protonmail.ch>
This commit is contained in:
58
src/App.tsx
58
src/App.tsx
@ -9,7 +9,12 @@ import { DebugPanel } from './components/DebugPanel'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { asyncLexer } from './lang/tokeniser'
|
||||
import { abstractSyntaxTree } from './lang/abstractSyntaxTree'
|
||||
import { _executor, ExtrudeGroup, SketchGroup } from './lang/executor'
|
||||
import {
|
||||
_executor,
|
||||
ProgramMemory,
|
||||
ExtrudeGroup,
|
||||
SketchGroup,
|
||||
} from './lang/executor'
|
||||
import CodeMirror from '@uiw/react-codemirror'
|
||||
import { langs } from '@uiw/codemirror-extensions-langs'
|
||||
import { linter, lintGutter } from '@codemirror/lint'
|
||||
@ -234,7 +239,7 @@ export function App() {
|
||||
}
|
||||
engineCommandManager.startNewSession()
|
||||
setEngineCommandManager(engineCommandManager)
|
||||
_executor(
|
||||
const programMemory = await _executor(
|
||||
_ast,
|
||||
{
|
||||
root: {
|
||||
@ -276,39 +281,28 @@ export function App() {
|
||||
engineCommandManager,
|
||||
{ bodyType: 'root' },
|
||||
[]
|
||||
).then(async (programMemory) => {
|
||||
const { artifactMap, sourceRangeMap } =
|
||||
await engineCommandManager.waitForAllCommands()
|
||||
)
|
||||
|
||||
setArtifactMap({ artifactMap, sourceRangeMap })
|
||||
engineCommandManager.onHover((id) => {
|
||||
if (!id) {
|
||||
setHighlightRange([0, 0])
|
||||
} else {
|
||||
const sourceRange = sourceRangeMap[id]
|
||||
setHighlightRange(sourceRange)
|
||||
}
|
||||
})
|
||||
engineCommandManager.onClick(({ id, type }) => {
|
||||
setCursor2({ range: sourceRangeMap[id], type })
|
||||
})
|
||||
setProgramMemory(programMemory)
|
||||
const geos = programMemory?.return
|
||||
?.map(({ name }: { name: string }) => {
|
||||
const artifact = programMemory?.root?.[name]
|
||||
if (
|
||||
artifact.type === 'extrudeGroup' ||
|
||||
artifact.type === 'sketchGroup'
|
||||
) {
|
||||
return artifact
|
||||
}
|
||||
return null
|
||||
})
|
||||
.filter((a) => a) as (ExtrudeGroup | SketchGroup)[]
|
||||
const { artifactMap, sourceRangeMap } =
|
||||
await engineCommandManager.waitForAllCommands()
|
||||
|
||||
// console.log(programMemory)
|
||||
setError()
|
||||
setArtifactMap({ artifactMap, sourceRangeMap })
|
||||
engineCommandManager.onHover((id) => {
|
||||
if (!id) {
|
||||
setHighlightRange([0, 0])
|
||||
} else {
|
||||
const sourceRange = sourceRangeMap[id]
|
||||
setHighlightRange(sourceRange)
|
||||
}
|
||||
})
|
||||
engineCommandManager.onClick(({ id, type }) => {
|
||||
setCursor2({ range: sourceRangeMap[id], type })
|
||||
})
|
||||
if (programMemory !== undefined) {
|
||||
setProgramMemory(programMemory)
|
||||
}
|
||||
|
||||
setError()
|
||||
} catch (e: any) {
|
||||
if (e instanceof KCLError) {
|
||||
addKCLError(e)
|
||||
|
@ -6,6 +6,7 @@ import { ProgramMemory, Path, SketchGroup } from './executor'
|
||||
import { initPromise } from './rust'
|
||||
import { enginelessExecutor } from '../lib/testHelpers'
|
||||
import { vi } from 'vitest'
|
||||
import { KCLUndefinedValueError } from './errors'
|
||||
|
||||
beforeAll(() => initPromise)
|
||||
|
||||
@ -440,6 +441,22 @@ describe('testing math operators', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('Testing Errors', () => {
|
||||
it('should throw an error when a variable is not defined', async () => {
|
||||
const code = `const myVar = 5
|
||||
const theExtrude = startSketchAt([0, 0])
|
||||
|> line([-2.4, 5], %)
|
||||
|> line([-0.76], myVarZ, %)
|
||||
|> line([5,5], %)
|
||||
|> close(%)
|
||||
|> extrude(4, %)
|
||||
show(theExtrude)`
|
||||
await expect(exe(code)).rejects.toEqual(
|
||||
new KCLUndefinedValueError('Memory item myVarZ not found', [[100, 106]])
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
// helpers
|
||||
|
||||
async function exe(
|
||||
|
@ -222,9 +222,11 @@ export const _executor = async (
|
||||
}
|
||||
const { body } = node
|
||||
const proms: Promise<any>[] = []
|
||||
body.forEach(async (statement, bodyIndex) => {
|
||||
for (let bodyIndex = 0; bodyIndex < body.length; bodyIndex++) {
|
||||
const statement = body[bodyIndex]
|
||||
if (statement.type === 'VariableDeclaration') {
|
||||
statement.declarations.forEach(async (declaration, index) => {
|
||||
for (let index = 0; index < statement.declarations.length; index++) {
|
||||
const declaration = statement.declarations[index]
|
||||
const variableName = declaration.id.name
|
||||
const pathToNode: PathToNode = [
|
||||
...previousPathToNode,
|
||||
@ -520,7 +522,7 @@ export const _executor = async (
|
||||
[[declaration.start, declaration.end]]
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
} else if (statement.type === 'ExpressionStatement') {
|
||||
const expression = statement.expression
|
||||
if (expression.type === 'CallExpression') {
|
||||
@ -560,7 +562,7 @@ export const _executor = async (
|
||||
_programMemory.return = await prom
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
await Promise.all(proms)
|
||||
return _programMemory
|
||||
}
|
||||
|
Reference in New Issue
Block a user