Fix artifact graph to survive when there's an execution error (#5246)
This also changes artifact graph errors to point to the KCL that the command originated from.
This commit is contained in:
@ -158,6 +158,12 @@ export function isTopLevelModule(range: SourceRange): boolean {
|
|||||||
return range[2] === 0
|
return range[2] === 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function firstSourceRange(error: RustKclError): SourceRange {
|
||||||
|
return error.sourceRanges.length > 0
|
||||||
|
? sourceRangeFromRust(error.sourceRanges[0])
|
||||||
|
: defaultSourceRange()
|
||||||
|
}
|
||||||
|
|
||||||
export const wasmUrl = () => {
|
export const wasmUrl = () => {
|
||||||
// For when we're in electron (file based) or web server (network based)
|
// For when we're in electron (file based) or web server (network based)
|
||||||
// For some reason relative paths don't work as expected. Otherwise we would
|
// For some reason relative paths don't work as expected. Otherwise we would
|
||||||
@ -255,7 +261,7 @@ export const parse = (code: string | Error): ParseResult | Error => {
|
|||||||
return new KCLError(
|
return new KCLError(
|
||||||
parsed.kind,
|
parsed.kind,
|
||||||
parsed.msg,
|
parsed.msg,
|
||||||
sourceRangeFromRust(parsed.sourceRanges[0]),
|
firstSourceRange(parsed),
|
||||||
[],
|
[],
|
||||||
[],
|
[],
|
||||||
defaultArtifactGraph()
|
defaultArtifactGraph()
|
||||||
@ -622,7 +628,7 @@ export const executor = async (
|
|||||||
const kclError = new KCLError(
|
const kclError = new KCLError(
|
||||||
parsed.error.kind,
|
parsed.error.kind,
|
||||||
parsed.error.msg,
|
parsed.error.msg,
|
||||||
sourceRangeFromRust(parsed.error.sourceRanges[0]),
|
firstSourceRange(parsed.error),
|
||||||
parsed.operations,
|
parsed.operations,
|
||||||
parsed.artifactCommands,
|
parsed.artifactCommands,
|
||||||
rustArtifactGraphToMap(parsed.artifactGraph)
|
rustArtifactGraphToMap(parsed.artifactGraph)
|
||||||
@ -691,7 +697,7 @@ export const modifyAstForSketch = async (
|
|||||||
const kclError = new KCLError(
|
const kclError = new KCLError(
|
||||||
parsed.kind,
|
parsed.kind,
|
||||||
parsed.msg,
|
parsed.msg,
|
||||||
sourceRangeFromRust(parsed.sourceRanges[0]),
|
firstSourceRange(parsed),
|
||||||
[],
|
[],
|
||||||
[],
|
[],
|
||||||
defaultArtifactGraph()
|
defaultArtifactGraph()
|
||||||
@ -762,7 +768,7 @@ export function programMemoryInit(): ProgramMemory | Error {
|
|||||||
return new KCLError(
|
return new KCLError(
|
||||||
parsed.kind,
|
parsed.kind,
|
||||||
parsed.msg,
|
parsed.msg,
|
||||||
sourceRangeFromRust(parsed.sourceRanges[0]),
|
firstSourceRange(parsed),
|
||||||
[],
|
[],
|
||||||
[],
|
[],
|
||||||
defaultArtifactGraph()
|
defaultArtifactGraph()
|
||||||
|
@ -12,6 +12,7 @@ use serde::{ser::SerializeSeq, Deserialize, Serialize};
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
errors::KclErrorDetails,
|
||||||
parsing::ast::types::{Node, Program},
|
parsing::ast::types::{Node, Program},
|
||||||
KclError, SourceRange,
|
KclError, SourceRange,
|
||||||
};
|
};
|
||||||
@ -595,9 +596,12 @@ fn artifacts_to_update(
|
|||||||
}
|
}
|
||||||
ModelingCmd::EnableSketchMode(_) => {
|
ModelingCmd::EnableSketchMode(_) => {
|
||||||
let current_plane_id = current_plane_id.ok_or_else(|| {
|
let current_plane_id = current_plane_id.ok_or_else(|| {
|
||||||
KclError::internal(format!(
|
KclError::Internal(KclErrorDetails {
|
||||||
"Expected a current plane ID when processing EnableSketchMode command, but we have none: {id:?}"
|
message: format!(
|
||||||
))
|
"Expected a current plane ID when processing EnableSketchMode command, but we have none: {id:?}"
|
||||||
|
),
|
||||||
|
source_ranges: vec![range],
|
||||||
|
})
|
||||||
})?;
|
})?;
|
||||||
let existing_plane = artifacts.get(&ArtifactId::new(current_plane_id));
|
let existing_plane = artifacts.get(&ArtifactId::new(current_plane_id));
|
||||||
match existing_plane {
|
match existing_plane {
|
||||||
@ -626,9 +630,12 @@ fn artifacts_to_update(
|
|||||||
ModelingCmd::StartPath(_) => {
|
ModelingCmd::StartPath(_) => {
|
||||||
let mut return_arr = Vec::new();
|
let mut return_arr = Vec::new();
|
||||||
let current_plane_id = current_plane_id.ok_or_else(|| {
|
let current_plane_id = current_plane_id.ok_or_else(|| {
|
||||||
KclError::internal(format!(
|
KclError::Internal(KclErrorDetails {
|
||||||
"Expected a current plane ID when processing StartPath command, but we have none: {id:?}"
|
message: format!(
|
||||||
))
|
"Expected a current plane ID when processing StartPath command, but we have none: {id:?}"
|
||||||
|
),
|
||||||
|
source_ranges: vec![range],
|
||||||
|
})
|
||||||
})?;
|
})?;
|
||||||
return_arr.push(Artifact::Path(Path {
|
return_arr.push(Artifact::Path(Path {
|
||||||
id,
|
id,
|
||||||
@ -730,9 +737,10 @@ fn artifacts_to_update(
|
|||||||
// TODO: Using the first one. Make sure to revisit this
|
// TODO: Using the first one. Make sure to revisit this
|
||||||
// choice, don't think it matters for now.
|
// choice, don't think it matters for now.
|
||||||
path_id: ArtifactId::new(*loft_cmd.section_ids.first().ok_or_else(|| {
|
path_id: ArtifactId::new(*loft_cmd.section_ids.first().ok_or_else(|| {
|
||||||
KclError::internal(format!(
|
KclError::Internal(KclErrorDetails {
|
||||||
"Expected at least one section ID in Loft command: {id:?}; cmd={cmd:?}"
|
message: format!("Expected at least one section ID in Loft command: {id:?}; cmd={cmd:?}"),
|
||||||
))
|
source_ranges: vec![range],
|
||||||
|
})
|
||||||
})?),
|
})?),
|
||||||
surface_ids: Vec::new(),
|
surface_ids: Vec::new(),
|
||||||
edge_ids: Vec::new(),
|
edge_ids: Vec::new(),
|
||||||
@ -772,9 +780,12 @@ fn artifacts_to_update(
|
|||||||
};
|
};
|
||||||
last_path = Some(path);
|
last_path = Some(path);
|
||||||
let path_sweep_id = path.sweep_id.ok_or_else(|| {
|
let path_sweep_id = path.sweep_id.ok_or_else(|| {
|
||||||
KclError::internal(format!(
|
KclError::Internal(KclErrorDetails {
|
||||||
"Expected a sweep ID on the path when processing Solid3dGetExtrusionFaceInfo command, but we have none: {id:?}, {path:?}"
|
message:format!(
|
||||||
))
|
"Expected a sweep ID on the path when processing Solid3dGetExtrusionFaceInfo command, but we have none: {id:?}, {path:?}"
|
||||||
|
),
|
||||||
|
source_ranges: vec![range],
|
||||||
|
})
|
||||||
})?;
|
})?;
|
||||||
return_arr.push(Artifact::Wall(Wall {
|
return_arr.push(Artifact::Wall(Wall {
|
||||||
id: face_id,
|
id: face_id,
|
||||||
@ -803,9 +814,12 @@ fn artifacts_to_update(
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let path_sweep_id = path.sweep_id.ok_or_else(|| {
|
let path_sweep_id = path.sweep_id.ok_or_else(|| {
|
||||||
KclError::internal(format!(
|
KclError::Internal(KclErrorDetails {
|
||||||
"Expected a sweep ID on the path when processing Solid3dGetExtrusionFaceInfo command, but we have none: {id:?}, {path:?}"
|
message:format!(
|
||||||
))
|
"Expected a sweep ID on the path when processing Solid3dGetExtrusionFaceInfo command, but we have none: {id:?}, {path:?}"
|
||||||
|
),
|
||||||
|
source_ranges: vec![range],
|
||||||
|
})
|
||||||
})?;
|
})?;
|
||||||
return_arr.push(Artifact::Cap(Cap {
|
return_arr.push(Artifact::Cap(Cap {
|
||||||
id: face_id,
|
id: face_id,
|
||||||
@ -848,17 +862,23 @@ fn artifacts_to_update(
|
|||||||
let response_edge_id = match response {
|
let response_edge_id = match response {
|
||||||
OkModelingCmdResponse::Solid3dGetNextAdjacentEdge(r) => {
|
OkModelingCmdResponse::Solid3dGetNextAdjacentEdge(r) => {
|
||||||
let Some(edge_id) = r.edge else {
|
let Some(edge_id) = r.edge else {
|
||||||
return Err(KclError::internal(format!(
|
return Err(KclError::Internal(KclErrorDetails {
|
||||||
"Expected Solid3dGetNextAdjacentEdge response to have an edge ID, but found none: id={id:?}, {response:?}"
|
message:format!(
|
||||||
)));
|
"Expected Solid3dGetNextAdjacentEdge response to have an edge ID, but found none: id={id:?}, {response:?}"
|
||||||
|
),
|
||||||
|
source_ranges: vec![range],
|
||||||
|
}));
|
||||||
};
|
};
|
||||||
edge_id.into()
|
edge_id.into()
|
||||||
}
|
}
|
||||||
OkModelingCmdResponse::Solid3dGetOppositeEdge(r) => r.edge.into(),
|
OkModelingCmdResponse::Solid3dGetOppositeEdge(r) => r.edge.into(),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(KclError::internal(format!(
|
return Err(KclError::Internal(KclErrorDetails {
|
||||||
"Expected Solid3dGetNextAdjacentEdge or Solid3dGetOppositeEdge response, but got: id={id:?}, {response:?}"
|
message:format!(
|
||||||
)));
|
"Expected Solid3dGetNextAdjacentEdge or Solid3dGetOppositeEdge response, but got: id={id:?}, {response:?}"
|
||||||
|
),
|
||||||
|
source_ranges: vec![range],
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user