KCL: Fix cryptic error in type mismatch (#5735)
Previous error message: "Expected a kcl_lib::execution::geometry::SolidSet but found Sketch" New error message: "Expected a SolidSet but found Sketch. You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`" Two improvements: - Don't print the fully-qualified Rust name (e.g. kcl_lib::executor::Solid) instead use the last part of that (e.g. just Solid) - Allow specific suggestions for combinations of got/want (e.g. "You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`") Closes #5616
This commit is contained in:
10
rust/Cargo.lock
generated
10
rust/Cargo.lock
generated
@ -1917,6 +1917,7 @@ dependencies = [
|
|||||||
"tower-lsp",
|
"tower-lsp",
|
||||||
"ts-rs",
|
"ts-rs",
|
||||||
"twenty-twenty",
|
"twenty-twenty",
|
||||||
|
"tynm",
|
||||||
"url",
|
"url",
|
||||||
"uuid",
|
"uuid",
|
||||||
"validator",
|
"validator",
|
||||||
@ -4242,6 +4243,15 @@ dependencies = [
|
|||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tynm"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd30d05e69d1478e13fe3e7a853409cfec82cebc2cf9b8d613b3c6b0081781ed"
|
||||||
|
dependencies = [
|
||||||
|
"nom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.17.0"
|
version = "1.17.0"
|
||||||
|
@ -78,6 +78,7 @@ ts-rs = { version = "10.1.0", features = [
|
|||||||
"no-serde-warnings",
|
"no-serde-warnings",
|
||||||
"serde-json-impl",
|
"serde-json-impl",
|
||||||
] }
|
] }
|
||||||
|
tynm = "0.1.10"
|
||||||
url = { version = "2.5.4", features = ["serde"] }
|
url = { version = "2.5.4", features = ["serde"] }
|
||||||
uuid = { workspace = true, features = ["v4", "js", "serde"] }
|
uuid = { workspace = true, features = ["v4", "js", "serde"] }
|
||||||
validator = { version = "0.20.0", features = ["derive"] }
|
validator = { version = "0.20.0", features = ["derive"] }
|
||||||
|
@ -857,7 +857,7 @@ part = rectShape([0, 0], 20, 20)
|
|||||||
};
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
err.error.message(),
|
err.error.message(),
|
||||||
"Expected a kcl_lib::std::shapes::SketchOrSurface but found string (text)"
|
"This function expected this argument to be of type SketchOrSurface but it's actually of type string (text)"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2086,6 +2086,26 @@ async fn kcl_test_ensure_nothing_left_in_batch_multi_file() {
|
|||||||
ctx.close().await;
|
ctx.close().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
|
async fn kcl_test_better_type_names() {
|
||||||
|
let code = r#"startSketchOn('XY')
|
||||||
|
|> circle(center = [-95.51, -74.7], radius = 262.23)
|
||||||
|
|> appearance(metalness = 0.9)
|
||||||
|
"#;
|
||||||
|
let result = execute_and_snapshot(code, UnitLength::Mm, None).await;
|
||||||
|
|
||||||
|
let err = match result.err() {
|
||||||
|
Some(x) => match x {
|
||||||
|
ExecError::Kcl(kcl_error_with_outputs) => kcl_error_with_outputs.error.message().to_owned(),
|
||||||
|
ExecError::Connection(_) => todo!(),
|
||||||
|
ExecError::BadPng(_) => todo!(),
|
||||||
|
ExecError::BadExport(_) => todo!(),
|
||||||
|
},
|
||||||
|
None => todo!(),
|
||||||
|
};
|
||||||
|
assert_eq!(err, "This function expected this argument to be of type SolidSet but it's actually of type Sketch. You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`");
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
async fn kcl_test_exporting_step_file() {
|
async fn kcl_test_exporting_step_file() {
|
||||||
// This tests export like how we do it in cli and kcl.py.
|
// This tests export like how we do it in cli and kcl.py.
|
||||||
|
@ -182,13 +182,22 @@ impl Args {
|
|||||||
}))?;
|
}))?;
|
||||||
|
|
||||||
T::from_kcl_val(&arg.value).ok_or_else(|| {
|
T::from_kcl_val(&arg.value).ok_or_else(|| {
|
||||||
|
let expected_type_name = tynm::type_name::<T>();
|
||||||
|
let actual_type_name = arg.value.human_friendly_type();
|
||||||
|
let msg_base = format!("This function expected this argument to be of type {expected_type_name} but it's actually of type {actual_type_name}");
|
||||||
|
let suggestion = match (expected_type_name.as_str(), actual_type_name) {
|
||||||
|
("SolidSet", "Sketch") => Some(
|
||||||
|
"You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`",
|
||||||
|
),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
let message = match suggestion {
|
||||||
|
None => msg_base,
|
||||||
|
Some(sugg) => format!("{msg_base}. {sugg}"),
|
||||||
|
};
|
||||||
KclError::Semantic(KclErrorDetails {
|
KclError::Semantic(KclErrorDetails {
|
||||||
source_ranges: arg.source_ranges(),
|
source_ranges: arg.source_ranges(),
|
||||||
message: format!(
|
message,
|
||||||
"Expected a {} but found {}",
|
|
||||||
type_name::<T>(),
|
|
||||||
arg.value.human_friendly_type()
|
|
||||||
),
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user