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:
26
src/App.tsx
26
src/App.tsx
@ -9,7 +9,12 @@ import { DebugPanel } from './components/DebugPanel'
|
|||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { asyncLexer } from './lang/tokeniser'
|
import { asyncLexer } from './lang/tokeniser'
|
||||||
import { abstractSyntaxTree } from './lang/abstractSyntaxTree'
|
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 CodeMirror from '@uiw/react-codemirror'
|
||||||
import { langs } from '@uiw/codemirror-extensions-langs'
|
import { langs } from '@uiw/codemirror-extensions-langs'
|
||||||
import { linter, lintGutter } from '@codemirror/lint'
|
import { linter, lintGutter } from '@codemirror/lint'
|
||||||
@ -234,7 +239,7 @@ export function App() {
|
|||||||
}
|
}
|
||||||
engineCommandManager.startNewSession()
|
engineCommandManager.startNewSession()
|
||||||
setEngineCommandManager(engineCommandManager)
|
setEngineCommandManager(engineCommandManager)
|
||||||
_executor(
|
const programMemory = await _executor(
|
||||||
_ast,
|
_ast,
|
||||||
{
|
{
|
||||||
root: {
|
root: {
|
||||||
@ -276,7 +281,8 @@ export function App() {
|
|||||||
engineCommandManager,
|
engineCommandManager,
|
||||||
{ bodyType: 'root' },
|
{ bodyType: 'root' },
|
||||||
[]
|
[]
|
||||||
).then(async (programMemory) => {
|
)
|
||||||
|
|
||||||
const { artifactMap, sourceRangeMap } =
|
const { artifactMap, sourceRangeMap } =
|
||||||
await engineCommandManager.waitForAllCommands()
|
await engineCommandManager.waitForAllCommands()
|
||||||
|
|
||||||
@ -292,23 +298,11 @@ export function App() {
|
|||||||
engineCommandManager.onClick(({ id, type }) => {
|
engineCommandManager.onClick(({ id, type }) => {
|
||||||
setCursor2({ range: sourceRangeMap[id], type })
|
setCursor2({ range: sourceRangeMap[id], type })
|
||||||
})
|
})
|
||||||
|
if (programMemory !== undefined) {
|
||||||
setProgramMemory(programMemory)
|
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)[]
|
|
||||||
|
|
||||||
// console.log(programMemory)
|
|
||||||
setError()
|
setError()
|
||||||
})
|
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
if (e instanceof KCLError) {
|
if (e instanceof KCLError) {
|
||||||
addKCLError(e)
|
addKCLError(e)
|
||||||
|
@ -6,6 +6,7 @@ import { ProgramMemory, Path, SketchGroup } from './executor'
|
|||||||
import { initPromise } from './rust'
|
import { initPromise } from './rust'
|
||||||
import { enginelessExecutor } from '../lib/testHelpers'
|
import { enginelessExecutor } from '../lib/testHelpers'
|
||||||
import { vi } from 'vitest'
|
import { vi } from 'vitest'
|
||||||
|
import { KCLUndefinedValueError } from './errors'
|
||||||
|
|
||||||
beforeAll(() => initPromise)
|
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
|
// helpers
|
||||||
|
|
||||||
async function exe(
|
async function exe(
|
||||||
|
@ -222,9 +222,11 @@ export const _executor = async (
|
|||||||
}
|
}
|
||||||
const { body } = node
|
const { body } = node
|
||||||
const proms: Promise<any>[] = []
|
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') {
|
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 variableName = declaration.id.name
|
||||||
const pathToNode: PathToNode = [
|
const pathToNode: PathToNode = [
|
||||||
...previousPathToNode,
|
...previousPathToNode,
|
||||||
@ -520,7 +522,7 @@ export const _executor = async (
|
|||||||
[[declaration.start, declaration.end]]
|
[[declaration.start, declaration.end]]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
} else if (statement.type === 'ExpressionStatement') {
|
} else if (statement.type === 'ExpressionStatement') {
|
||||||
const expression = statement.expression
|
const expression = statement.expression
|
||||||
if (expression.type === 'CallExpression') {
|
if (expression.type === 'CallExpression') {
|
||||||
@ -560,7 +562,7 @@ export const _executor = async (
|
|||||||
_programMemory.return = await prom
|
_programMemory.return = await prom
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
await Promise.all(proms)
|
await Promise.all(proms)
|
||||||
return _programMemory
|
return _programMemory
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user