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:
Adam Chalmers
2023-08-07 20:33:38 -05:00
committed by GitHub
parent 7a537eea8e
commit a986f76e70
3 changed files with 49 additions and 36 deletions

View File

@ -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)

View File

@ -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(

View File

@ -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
}