diff --git a/rust/kcl-lib/src/lsp/kcl/mod.rs b/rust/kcl-lib/src/lsp/kcl/mod.rs index bed5cc5ab..6bea88a11 100644 --- a/rust/kcl-lib/src/lsp/kcl/mod.rs +++ b/rust/kcl-lib/src/lsp/kcl/mod.rs @@ -1189,7 +1189,6 @@ impl LanguageServer for Backend { } async fn completion(&self, params: CompletionParams) -> RpcResult> { - // ADAM: This is the entrypoint. let mut completions = vec![CompletionItem { label: PIPE_OPERATOR.to_string(), label_details: None, diff --git a/rust/kcl-wasm-lib/src/context.rs b/rust/kcl-wasm-lib/src/context.rs index be1ad8a76..2581621f3 100644 --- a/rust/kcl-wasm-lib/src/context.rs +++ b/rust/kcl-wasm-lib/src/context.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use gloo_utils::format::JsValueSerdeExt; -use kcl_lib::{wasm_engine::FileManager, EngineManager, Program}; +use kcl_lib::{wasm_engine::FileManager, EngineManager, ExecOutcome, KclError, KclErrorWithOutputs, Program}; use wasm_bindgen::prelude::*; #[wasm_bindgen] @@ -56,7 +56,7 @@ impl Context { return Ok(kcl_lib::ExecutorContext::new_mock( self.mock_engine.clone(), self.fs.clone(), - settings.into(), + settings, )); } @@ -74,18 +74,38 @@ impl Context { program_ast_json: &str, path: Option, settings: &str, - ) -> Result { + ) -> Result { console_error_panic_hook::set_once(); - let program: Program = serde_json::from_str(program_ast_json).map_err(|e| e.to_string())?; + self.execute_typed(program_ast_json, path, settings) + .await + .and_then(|outcome|JsValue::from_serde(&outcome).map_err(|e| { + // The serde-wasm-bindgen does not work here because of weird HashMap issues. + // DO NOT USE serde_wasm_bindgen::to_value it will break the frontend. + KclErrorWithOutputs::no_outputs(KclError::internal( + format!("Could not serialize successful KCL result. This is a bug in KCL and not in your code, please report this to Zoo. Details: {e}"), + ))})) + .map_err(|e: KclErrorWithOutputs| JsValue::from_serde(&e).unwrap()) + } - let ctx = self.create_executor_ctx(settings, path, false)?; - match ctx.run_with_caching(program).await { - // The serde-wasm-bindgen does not work here because of weird HashMap issues. - // DO NOT USE serde_wasm_bindgen::to_value it will break the frontend. - Ok(outcome) => JsValue::from_serde(&outcome).map_err(|e| e.to_string()), - Err(err) => Err(serde_json::to_string(&err).map_err(|serde_err| serde_err.to_string())?), - } + async fn execute_typed( + &self, + program_ast_json: &str, + path: Option, + settings: &str, + ) -> Result { + let program: Program = serde_json::from_str(program_ast_json).map_err(|e| { + let err = KclError::internal( + format!("Could not deserialize KCL AST. This is a bug in KCL and not in your code, please report this to Zoo. Details: {e}"), + ); + KclErrorWithOutputs::no_outputs(err) + })?; + let ctx = self + .create_executor_ctx(settings, path, false) + .map_err(|e| KclErrorWithOutputs::no_outputs(KclError::internal( + format!("Could not create KCL executor context. This is a bug in KCL and not in your code, please report this to Zoo. Details: {e}"), + )))?; + ctx.run_with_caching(program).await } /// Reset the scene and bust the cache. diff --git a/src/lang/wasm.ts b/src/lang/wasm.ts index 4c9bc74a4..0f4c25437 100644 --- a/src/lang/wasm.ts +++ b/src/lang/wasm.ts @@ -389,7 +389,20 @@ export function sketchFromKclValue( } export const errFromErrWithOutputs = (e: any): KCLError => { - const parsed: KclErrorWithOutputs = JSON.parse(e.toString()) + // `e` is any, so let's figure out something useful to do with it. + const parsed: KclErrorWithOutputs = (() => { + // No need to parse, it's already an object. + if (typeof e === 'object') { + return e + } + // It's a string, so parse it. + if (typeof e === 'string') { + return JSON.parse(e) + } + // It can be converted to a string, then parsed. + return JSON.parse(e.toString()) + })() + return new KCLError( parsed.error.kind, parsed.error.details.msg,