From 1d77ca21b0fb7b603f46b35d8e2d925e16459af9 Mon Sep 17 00:00:00 2001 From: claycuy Date: Sun, 13 Sep 2026 21:22:17 +0800 Subject: [PATCH 01/10] feat: Added diagnostic links to error messages --- rust/src/modules/vmerror/error.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/src/modules/vmerror/error.rs b/rust/src/modules/vmerror/error.rs index 24f0640f..bcbfdcc7 100644 --- a/rust/src/modules/vmerror/error.rs +++ b/rust/src/modules/vmerror/error.rs @@ -8,6 +8,7 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ +// TODO: add here use smol_str::SmolStr; use std::borrow::Cow; #[derive(Debug)] From 8657c2c8f93a859155715793ddaec32f0a201d2a Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Sun, 13 Sep 2026 21:32:09 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=F0=9F=93=9D=20CodeRabbit=20Chat:=20Add?= =?UTF-8?q?=20VMError=20Diagnostic=20Links=20to=20Error=20Output=20(#584)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- rust/src/modules/vmerror/display.rs | 1 + rust/src/modules/vmerror/error.rs | 99 ++++++++++++++++++++++++++++- 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/rust/src/modules/vmerror/display.rs b/rust/src/modules/vmerror/display.rs index a1d9db54..b8a6d1d1 100644 --- a/rust/src/modules/vmerror/display.rs +++ b/rust/src/modules/vmerror/display.rs @@ -131,6 +131,7 @@ impl fmt::Display for VMError { } VMError::SystemError(s) => write!(f, "{}", s), }?; + write!(f, "\n{}", self.diagnostic_link())?; if !matches!(self, VMError::SystemError(_)) { if is_hint { write!( diff --git a/rust/src/modules/vmerror/error.rs b/rust/src/modules/vmerror/error.rs index bcbfdcc7..39b1e405 100644 --- a/rust/src/modules/vmerror/error.rs +++ b/rust/src/modules/vmerror/error.rs @@ -8,7 +8,6 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -// TODO: add here use smol_str::SmolStr; use std::borrow::Cow; #[derive(Debug)] @@ -104,4 +103,102 @@ impl VMError { VMError::SystemError(_) => "LVM500", } } + + /// Returns the documentation URL for this error. + #[cold] + pub fn diagnostic_link(&self) -> String { + format!( + "https://lightvm.vercel.app/api-reference/error-codes/{}-code", + self.error_code().to_ascii_lowercase() + ) + } +} + +#[cfg(test)] +mod tests { + use super::VMError; + use crate::modules::vmerror::config::set_thread_error_config; + use smol_str::SmolStr; + + fn all_errors() -> Vec { + vec![ + VMError::StackOverflow { ip: 1, limit: 2 }, + VMError::StackUnderflow { + ip: 1, + opcode: "POP", + }, + VMError::InvalidOpcode { + ip: 1, + code: SmolStr::new("INVALID"), + }, + VMError::TypeMismatch { + ip: 1, + expected: "number", + found: "string", + }, + VMError::SystemError(SmolStr::new("system failure")), + VMError::OutOfBounds { + ip: 1, + index: 2, + len: 1, + }, + VMError::InvalidJumpTarget { + ip: 1, + target: 2, + len: 1, + }, + VMError::FeatureRestricted { + ip: 1, + feature: "nightly", + }, + VMError::IoFlood { ip: 1 }, + VMError::ImportLimitReached { ip: 1 }, + VMError::UnauthorizedModule { + ip: 1, + module: SmolStr::new("module"), + }, + VMError::MemoryLimitExceeded { ip: 1 }, + VMError::CallLimitExceeded { ip: 1 }, + VMError::JumpLimitExceeded { ip: 1 }, + VMError::ExcessiveNopPadding, + VMError::InvalidMaxTicksConfig, + VMError::TickLimitExceeded, + ] + } + + #[test] + fn every_error_has_a_diagnostic_link_containing_its_code() { + for error in all_errors() { + assert!( + error + .diagnostic_link() + .to_ascii_uppercase() + .contains(error.error_code()), + "diagnostic link missing {}", + error.error_code() + ); + } + } + + #[test] + fn formatted_error_contains_its_diagnostic_link() { + let error = VMError::StackOverflow { ip: 1, limit: 2 }; + + assert!(error.to_string().contains(&error.diagnostic_link())); + } + + #[test] + fn formatted_system_error_contains_its_diagnostic_link() { + let error = VMError::SystemError(SmolStr::new("system failure")); + + assert!(error.to_string().contains(&error.diagnostic_link())); + } + + #[test] + fn diagnostic_link_is_rendered_when_hints_are_disabled() { + set_thread_error_config(false, false, false); + let error = VMError::StackOverflow { ip: 1, limit: 2 }; + + assert!(error.to_string().contains(&error.diagnostic_link())); + } } From b162442a89fb94938374409086328e858186bb77 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Sun, 13 Sep 2026 21:40:11 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=F0=9F=93=9D=20CodeRabbit=20Chat:=20Refin?= =?UTF-8?q?e=20Diagnostic=20Link=20Layout=20in=20VM=20Error=20Output=20(#5?= =?UTF-8?q?85)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- rust/src/modules/vmerror/display.rs | 6 ++++- rust/src/modules/vmerror/error.rs | 36 ++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/rust/src/modules/vmerror/display.rs b/rust/src/modules/vmerror/display.rs index b8a6d1d1..a54b1bb4 100644 --- a/rust/src/modules/vmerror/display.rs +++ b/rust/src/modules/vmerror/display.rs @@ -131,7 +131,6 @@ impl fmt::Display for VMError { } VMError::SystemError(s) => write!(f, "{}", s), }?; - write!(f, "\n{}", self.diagnostic_link())?; if !matches!(self, VMError::SystemError(_)) { if is_hint { write!( @@ -144,6 +143,11 @@ impl fmt::Display for VMError { write!(f, "\n {DARK_GRAY}error type: {}", err_type)?; } } + write!( + f, + "\n {RESET}{CYAN}├── {DARK_GRAY}documentation: {}{RESET}", + self.diagnostic_link() + )?; if is_backtrace { let backtrace = get_backtrace(); write!( diff --git a/rust/src/modules/vmerror/error.rs b/rust/src/modules/vmerror/error.rs index 39b1e405..230fc6c2 100644 --- a/rust/src/modules/vmerror/error.rs +++ b/rust/src/modules/vmerror/error.rs @@ -182,23 +182,53 @@ mod tests { #[test] fn formatted_error_contains_its_diagnostic_link() { + set_thread_error_config(false, false, true); let error = VMError::StackOverflow { ip: 1, limit: 2 }; + let formatted = error.to_string(); + let metadata_position = formatted.find("error type:").unwrap(); + let documentation_position = formatted.find("documentation:").unwrap(); + let hint_position = formatted.find("hint:").unwrap(); - assert!(error.to_string().contains(&error.diagnostic_link())); + assert!( + formatted.contains(&format!("documentation: {}", error.diagnostic_link())) + ); + assert!(formatted.contains("\x1b[36m├── \x1b[2;37mdocumentation:")); + assert!(metadata_position < documentation_position); + assert!(documentation_position < hint_position); } #[test] fn formatted_system_error_contains_its_diagnostic_link() { + set_thread_error_config(false, false, true); let error = VMError::SystemError(SmolStr::new("system failure")); + let formatted = error.to_string(); + let error_position = formatted.find("system failure").unwrap(); + let documentation_position = formatted.find("documentation:").unwrap(); + let hint_position = formatted.find("hint:").unwrap(); - assert!(error.to_string().contains(&error.diagnostic_link())); + assert!(formatted.contains(&error.diagnostic_link())); + assert!(error_position < documentation_position); + assert!(documentation_position < hint_position); } #[test] fn diagnostic_link_is_rendered_when_hints_are_disabled() { set_thread_error_config(false, false, false); let error = VMError::StackOverflow { ip: 1, limit: 2 }; + let formatted = error.to_string(); - assert!(error.to_string().contains(&error.diagnostic_link())); + assert!(formatted.contains(&error.diagnostic_link())); + assert!(formatted.contains("documentation:")); + } + + #[test] + fn diagnostic_link_is_rendered_before_backtrace() { + set_thread_error_config(true, false, true); + let error = VMError::StackOverflow { ip: 1, limit: 2 }; + let formatted = error.to_string(); + let documentation_position = formatted.find("documentation:").unwrap(); + let backtrace_position = formatted.find("internal backtrace:").unwrap(); + + assert!(documentation_position < backtrace_position); } } From ba39242acd88595b683a326c461aecae68a6fe20 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Sun, 13 Sep 2026 21:54:54 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=F0=9F=93=9D=20CodeRabbit=20Chat:=20Add?= =?UTF-8?q?=20configurable=20diagnostic=20links=20to=20VM=20error=20output?= =?UTF-8?q?=20(#586)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- rust/src/interfaces/interface.rs | 43 +++++++++++++++++++---- rust/src/interfaces/napi_interface.rs | 27 ++++++++++++++ rust/src/interfaces/native_interface.rs | 19 ++++++++++ rust/src/interfaces/wasm_interface.rs | 22 ++++++++++-- rust/src/modules/vmerror/config.rs | 6 +++- rust/src/modules/vmerror/display.rs | 13 ++++--- rust/src/modules/vmerror/error.rs | 20 +++++++---- rust/src/types/error_options.rs | 12 +++++++ rust/src/types/js/js_error_options.rs | 2 ++ rust/src/types/wasm/wasm_error_options.rs | 2 ++ 10 files changed, 144 insertions(+), 22 deletions(-) diff --git a/rust/src/interfaces/interface.rs b/rust/src/interfaces/interface.rs index 2b06b0ff..7844c67d 100644 --- a/rust/src/interfaces/interface.rs +++ b/rust/src/interfaces/interface.rs @@ -74,6 +74,7 @@ pub struct LightVM { pub backtrace: bool, pub explain: bool, pub hint: bool, + pub diagnostic_links: bool, } impl LightVM { pub fn new_node( @@ -82,6 +83,7 @@ impl LightVM { backtrace: bool, explain: bool, hint: bool, + diagnostic_links: bool, ) -> Self { use crate::types::value::Value; use crate::types::vmstate::VmState; @@ -114,6 +116,7 @@ impl LightVM { backtrace, explain, hint, + diagnostic_links, } } #[inline(always)] @@ -126,8 +129,13 @@ impl LightVM { } Ok(()) } - pub fn set_mode(&self, backtrace: bool, explain: bool, hint: bool) { - crate::modules::vmerror::config::set_thread_error_config(backtrace, explain, hint); + pub fn set_mode(&self, backtrace: bool, explain: bool, hint: bool, diagnostic_links: bool) { + crate::modules::vmerror::config::set_thread_error_config( + backtrace, + explain, + hint, + diagnostic_links, + ); } pub fn index_metadata(&mut self) { self.functions.clear(); @@ -169,7 +177,12 @@ impl LightVM { get_versions() } pub fn load_internal(&mut self, source: String) -> Result<(), VMError> { - self.set_mode(self.backtrace, self.explain, self.hint); + self.set_mode( + self.backtrace, + self.explain, + self.hint, + self.diagnostic_links, + ); crate::modules::vmerror::get_backtrace::clear_backtrace(); if self.backtrace { crate::modules::vmerror::get_backtrace::capture_backtrace(); @@ -229,7 +242,12 @@ impl LightVM { Ok(()) } pub fn run_internal(&mut self, options: Option) -> Result { - self.set_mode(self.backtrace, self.explain, self.hint); + self.set_mode( + self.backtrace, + self.explain, + self.hint, + self.diagnostic_links, + ); crate::modules::vmerror::get_backtrace::clear_backtrace(); if self.backtrace { crate::modules::vmerror::get_backtrace::capture_backtrace(); @@ -280,7 +298,12 @@ impl LightVM { } #[inline] pub fn compile_internal(&mut self, config: CompileConfig) -> Result<(), VMError> { - self.set_mode(self.backtrace, self.explain, self.hint); + self.set_mode( + self.backtrace, + self.explain, + self.hint, + self.diagnostic_links, + ); crate::modules::vmerror::get_backtrace::clear_backtrace(); if self.backtrace { crate::modules::vmerror::get_backtrace::capture_backtrace(); @@ -498,7 +521,12 @@ impl LightVM { bytecode_raw: serde_json::Value, ) -> Result { self.require(Capability::Control)?; - self.set_mode(self.backtrace, self.explain, self.hint); + self.set_mode( + self.backtrace, + self.explain, + self.hint, + self.diagnostic_links, + ); crate::modules::vmerror::get_backtrace::clear_backtrace(); if self.backtrace { crate::modules::vmerror::get_backtrace::capture_backtrace(); @@ -642,6 +670,7 @@ mod tests { backtrace: false, explain: false, hint: true, + diagnostic_links: true, } } #[test] @@ -904,7 +933,7 @@ mod tests { vm.backtrace = true; vm.explain = true; vm.hint = false; - set_thread_error_config(false, false, true); + set_thread_error_config(false, false, true, true); let before = get_thread_or_global_config(); let result = vm.optimize_bytecode_internal(serde_json::json!([["noop"]])); let after = get_thread_or_global_config(); diff --git a/rust/src/interfaces/napi_interface.rs b/rust/src/interfaces/napi_interface.rs index a7b3092e..aede8e80 100644 --- a/rust/src/interfaces/napi_interface.rs +++ b/rust/src/interfaces/napi_interface.rs @@ -103,6 +103,7 @@ impl NodeLightVM { backtrace: error_options.backtrace.unwrap_or(false), explain: error_options.explain.unwrap_or(false), hint: error_options.hint.unwrap_or(true), + diagnostic_links: error_options.diagnostic_links.unwrap_or(true), }, }) } @@ -187,6 +188,11 @@ impl NodeLightVM { self.inner.hint = enabled; Ok(()) } + #[napi(js_name = "withDiagnosticLinks")] + pub fn with_diagnostic_links(&mut self, enabled: bool) -> Result<()> { + self.inner.diagnostic_links = enabled; + Ok(()) + } #[napi] pub fn info(&mut self) -> Result { let info_vm = self.inner.info_internal(); @@ -561,6 +567,7 @@ impl NodeLightVM { is_backtrace, is_explain, is_hint, + self.inner.diagnostic_links, ); vm_instance.caps = self .inner @@ -599,6 +606,7 @@ impl NodeLightVM { #[cfg(test)] mod tests { use super::*; + use crate::types::js::js_error_options::JSErrorOptions; #[test] fn unknown_capability_uses_vm_error_display() { let config = VmNapiConfig { @@ -717,4 +725,23 @@ mod tests { r#"[["stop"]]"# ); } + #[test] + fn diagnostic_links_can_be_configured_and_updated() { + let mut vm = NodeLightVM::napi_new(VmNapiConfig { + error_options: Some(JSErrorOptions { + diagnostic_links: Some(false), + ..Default::default() + }), + ..Default::default() + }) + .expect("expected a VM"); + + assert!(!vm.inner.diagnostic_links); + vm.with_diagnostic_links(true) + .expect("expected the setting to update"); + assert!(vm.inner.diagnostic_links); + vm.with_diagnostic_links(false) + .expect("expected the setting to update"); + assert!(!vm.inner.diagnostic_links); + } } diff --git a/rust/src/interfaces/native_interface.rs b/rust/src/interfaces/native_interface.rs index 4eca12d1..683ffd6c 100644 --- a/rust/src/interfaces/native_interface.rs +++ b/rust/src/interfaces/native_interface.rs @@ -225,6 +225,7 @@ impl LightVM { backtrace: error_options.backtrace, explain: error_options.explain, hint: error_options.hint, + diagnostic_links: error_options.diagnostic_links, } } pub fn set_max_io(mut self, value: usize) -> Self { @@ -283,6 +284,10 @@ impl LightVM { self.hint = enabled; self } + pub fn with_diagnostic_links(mut self, enabled: bool) -> Self { + self.diagnostic_links = enabled; + self + } #[cfg(not(feature = "wasm"))] pub fn info(&mut self) -> InfoVM { self.info_internal() @@ -464,6 +469,7 @@ impl LightVM { backtrace: self.backtrace, explain: self.explain, hint: self.hint, + diagnostic_links: self.diagnostic_links, time_budget: self.time_budget, can_control: self.caps.contains(&Capability::Control), can_debug: self.caps.contains(&Capability::Debug), @@ -475,6 +481,7 @@ pub struct LightVMTools { pub backtrace: bool, pub explain: bool, pub hint: bool, + pub diagnostic_links: bool, pub time_budget: TimeBudget, pub can_control: bool, pub can_debug: bool, @@ -534,6 +541,7 @@ impl LightVMTools { backtrace: self.backtrace, explain: self.explain, hint: self.hint, + diagnostic_links: self.diagnostic_links, }), }; let opt_str = LightVM::new(config) @@ -628,6 +636,15 @@ mod tests { assert_eq!(vm.state, VmState::Idle); } #[test] + fn diagnostic_links_can_be_disabled() { + let mut vm = LightVM::new(VmConfig::default()).with_diagnostic_links(false); + let error = vm + .load_internal("invalid source".to_string()) + .expect_err("expected invalid source to fail"); + + assert!(!error.to_string().contains("documentation:")); + } + #[test] fn on_registers_listener() { let config = VmConfig { caps: vec![], @@ -818,6 +835,7 @@ mod tests { backtrace: tools.backtrace, explain: tools.explain, hint: tools.hint, + diagnostic_links: tools.diagnostic_links, }), ..Default::default() }); @@ -845,6 +863,7 @@ mod tests { backtrace: tools.backtrace, explain: tools.explain, hint: tools.hint, + diagnostic_links: tools.diagnostic_links, }), ..Default::default() }); diff --git a/rust/src/interfaces/wasm_interface.rs b/rust/src/interfaces/wasm_interface.rs index 60b71c55..82873b5e 100644 --- a/rust/src/interfaces/wasm_interface.rs +++ b/rust/src/interfaces/wasm_interface.rs @@ -102,6 +102,7 @@ impl WasmLightVM { backtrace: error_options.backtrace.unwrap_or(false), explain: error_options.explain.unwrap_or(false), hint: error_options.hint.unwrap_or(true), + diagnostic_links: error_options.diagnostic_links.unwrap_or(true), }, }) } @@ -173,6 +174,10 @@ impl WasmLightVM { pub fn with_hint(&mut self, enabled: bool) { self.inner.hint = enabled; } + #[wasm_bindgen(js_name = "withDiagnosticLinks")] + pub fn with_diagnostic_links(&mut self, enabled: bool) { + self.inner.diagnostic_links = enabled; + } #[wasm_bindgen] pub fn load(&mut self, source: String) -> Result<(), JsValue> { self @@ -384,6 +389,7 @@ impl WasmLightVM { backtrace: self.inner.backtrace, explain: self.inner.explain, hint: self.inner.hint, + diagnostic_links: self.inner.diagnostic_links, time_budget: self.inner.time_budget, can_observe: self.inner.caps.contains(&Capability::Observe), can_control: self.inner.caps.contains(&Capability::Control), @@ -398,6 +404,7 @@ pub struct WasmLightVMTools { pub backtrace: bool, pub explain: bool, pub hint: bool, + pub diagnostic_links: bool, time_budget: TimeBudget, pub can_observe: bool, pub can_control: bool, @@ -417,6 +424,7 @@ impl WasmLightVMTools { self.backtrace, self.explain, self.hint, + self.diagnostic_links, ); vm_instance.caps = { let mut caps = HashSet::new(); @@ -506,7 +514,7 @@ mod tests { use super::*; use crate::types::security_config::SecurityConfig; fn vm_with_control_capability() -> WasmLightVM { - let mut inner = LightVM::new_node(SecurityConfig::default(), false, false, false, true); + let mut inner = LightVM::new_node(SecurityConfig::default(), false, false, false, true, true); inner.caps.insert(Capability::Control); WasmLightVM { inner } } @@ -515,10 +523,14 @@ mod tests { let json_data = serde_json::json!({ "caps": [0, 2], "runtimeConfig": { "nightly": true }, - "errorOptions": { "hint": true } + "errorOptions": { "hint": true, "diagnosticLinks": false } }); let config: VmWasmConfig = serde_json::from_value(json_data).unwrap(); assert_eq!(config.caps, vec![0, 2]); + assert_eq!( + config.error_options.as_ref().unwrap().diagnostic_links, + Some(false) + ); #[cfg(target_arch = "wasm32")] { let mut vm = WasmLightVM::new(serde_wasm_bindgen::to_value(&config).unwrap()).unwrap(); @@ -530,6 +542,12 @@ mod tests { assert_eq!(config.runtime_config.unwrap().nightly, Some(true)); } #[test] + fn diagnostic_links_can_be_updated() { + let mut vm = vm_with_control_capability(); + vm.with_diagnostic_links(false); + assert!(!vm.inner.diagnostic_links); + } + #[test] fn start_and_finish_event_names_are_supported() { assert_eq!(parse_event("start"), Some(VmEvent::Start)); assert_eq!(parse_event("finish"), Some(VmEvent::Finish)); diff --git a/rust/src/modules/vmerror/config.rs b/rust/src/modules/vmerror/config.rs index 2e3b1f57..34dc2aca 100644 --- a/rust/src/modules/vmerror/config.rs +++ b/rust/src/modules/vmerror/config.rs @@ -15,6 +15,7 @@ pub struct VMErrorContainer { pub backtrace: bool, pub explain: bool, pub hint: bool, + pub diagnostic_links: bool, } impl Default for VMErrorContainer { fn default() -> Self { @@ -27,6 +28,7 @@ impl VMErrorContainer { backtrace: false, explain: false, hint: true, + diagnostic_links: true, } } pub fn get_value(&self) -> VMErrorContainer { @@ -34,6 +36,7 @@ impl VMErrorContainer { backtrace: self.backtrace, explain: self.explain, hint: self.hint, + diagnostic_links: self.diagnostic_links, } } } @@ -41,12 +44,13 @@ thread_local! { static THREAD_ERROR_CONFIG: RefCell> = const { RefCell::new(None) }; } static EXPLAIN_MODE: OnceLock> = OnceLock::new(); -pub fn set_thread_error_config(backtrace: bool, explain: bool, hint: bool) { +pub fn set_thread_error_config(backtrace: bool, explain: bool, hint: bool, diagnostic_links: bool) { THREAD_ERROR_CONFIG.with(|config| { *config.borrow_mut() = Some(VMErrorContainer { backtrace, explain, hint, + diagnostic_links, }); }); } diff --git a/rust/src/modules/vmerror/display.rs b/rust/src/modules/vmerror/display.rs index a54b1bb4..2a1021fe 100644 --- a/rust/src/modules/vmerror/display.rs +++ b/rust/src/modules/vmerror/display.rs @@ -22,6 +22,7 @@ impl fmt::Display for VMError { let is_backtrace = config.backtrace; let is_explain = config.explain; let is_hint = config.hint; + let diagnostic_links = config.diagnostic_links; let err_type = match self { VMError::StackOverflow { .. } => "StackOverflow", VMError::StackUnderflow { .. } => "StackUnderflow", @@ -143,11 +144,13 @@ impl fmt::Display for VMError { write!(f, "\n {DARK_GRAY}error type: {}", err_type)?; } } - write!( - f, - "\n {RESET}{CYAN}├── {DARK_GRAY}documentation: {}{RESET}", - self.diagnostic_link() - )?; + if diagnostic_links { + write!( + f, + "\n {RESET}{CYAN}├── {DARK_GRAY}documentation: {}{RESET}", + self.diagnostic_link() + )?; + } if is_backtrace { let backtrace = get_backtrace(); write!( diff --git a/rust/src/modules/vmerror/error.rs b/rust/src/modules/vmerror/error.rs index 230fc6c2..f215cde1 100644 --- a/rust/src/modules/vmerror/error.rs +++ b/rust/src/modules/vmerror/error.rs @@ -182,16 +182,14 @@ mod tests { #[test] fn formatted_error_contains_its_diagnostic_link() { - set_thread_error_config(false, false, true); + set_thread_error_config(false, false, true, true); let error = VMError::StackOverflow { ip: 1, limit: 2 }; let formatted = error.to_string(); let metadata_position = formatted.find("error type:").unwrap(); let documentation_position = formatted.find("documentation:").unwrap(); let hint_position = formatted.find("hint:").unwrap(); - assert!( - formatted.contains(&format!("documentation: {}", error.diagnostic_link())) - ); + assert!(formatted.contains(&format!("documentation: {}", error.diagnostic_link()))); assert!(formatted.contains("\x1b[36m├── \x1b[2;37mdocumentation:")); assert!(metadata_position < documentation_position); assert!(documentation_position < hint_position); @@ -199,7 +197,7 @@ mod tests { #[test] fn formatted_system_error_contains_its_diagnostic_link() { - set_thread_error_config(false, false, true); + set_thread_error_config(false, false, true, true); let error = VMError::SystemError(SmolStr::new("system failure")); let formatted = error.to_string(); let error_position = formatted.find("system failure").unwrap(); @@ -213,7 +211,7 @@ mod tests { #[test] fn diagnostic_link_is_rendered_when_hints_are_disabled() { - set_thread_error_config(false, false, false); + set_thread_error_config(false, false, false, true); let error = VMError::StackOverflow { ip: 1, limit: 2 }; let formatted = error.to_string(); @@ -223,7 +221,7 @@ mod tests { #[test] fn diagnostic_link_is_rendered_before_backtrace() { - set_thread_error_config(true, false, true); + set_thread_error_config(true, false, true, true); let error = VMError::StackOverflow { ip: 1, limit: 2 }; let formatted = error.to_string(); let documentation_position = formatted.find("documentation:").unwrap(); @@ -231,4 +229,12 @@ mod tests { assert!(documentation_position < backtrace_position); } + + #[test] + fn diagnostic_link_can_be_disabled() { + set_thread_error_config(false, false, true, false); + let error = VMError::StackOverflow { ip: 1, limit: 2 }; + + assert!(!error.to_string().contains("documentation:")); + } } diff --git a/rust/src/types/error_options.rs b/rust/src/types/error_options.rs index 1445e34d..202ad519 100644 --- a/rust/src/types/error_options.rs +++ b/rust/src/types/error_options.rs @@ -13,6 +13,7 @@ pub struct ErrorOptions { pub backtrace: bool, pub explain: bool, pub hint: bool, + pub diagnostic_links: bool, } impl Default for ErrorOptions { fn default() -> Self { @@ -20,6 +21,17 @@ impl Default for ErrorOptions { backtrace: false, explain: false, hint: true, + diagnostic_links: true, } } } + +#[cfg(test)] +mod tests { + use super::ErrorOptions; + + #[test] + fn diagnostic_links_are_enabled_by_default() { + assert!(ErrorOptions::default().diagnostic_links); + } +} diff --git a/rust/src/types/js/js_error_options.rs b/rust/src/types/js/js_error_options.rs index 52e7f919..28470507 100644 --- a/rust/src/types/js/js_error_options.rs +++ b/rust/src/types/js/js_error_options.rs @@ -18,4 +18,6 @@ pub struct JSErrorOptions { pub backtrace: Option, pub explain: Option, pub hint: Option, + #[ts(rename = "diagnosticLinks")] + pub diagnostic_links: Option, } diff --git a/rust/src/types/wasm/wasm_error_options.rs b/rust/src/types/wasm/wasm_error_options.rs index 031f8044..74dd03b1 100644 --- a/rust/src/types/wasm/wasm_error_options.rs +++ b/rust/src/types/wasm/wasm_error_options.rs @@ -12,8 +12,10 @@ use serde::{Deserialize, Serialize}; #[cfg(feature = "wasm")] #[derive(Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct WASMErrorOptions { pub backtrace: Option, pub explain: Option, pub hint: Option, + pub diagnostic_links: Option, } From 7aa98e466cb6a08d168a0cebf9ac014c6df761e5 Mon Sep 17 00:00:00 2001 From: Claycuy Date: Mon, 14 Sep 2026 09:05:05 +0800 Subject: [PATCH 05/10] refactor: Clean up source code --- cspell.config.js | 3 ++- rust/src/interfaces/napi_interface.rs | 1 - rust/src/interfaces/native_interface.rs | 1 - rust/src/modules/vmerror/error.rs | 14 -------------- rust/src/types/error_options.rs | 2 -- 5 files changed, 2 insertions(+), 19 deletions(-) diff --git a/cspell.config.js b/cspell.config.js index 0157c380..0db707ce 100644 --- a/cspell.config.js +++ b/cspell.config.js @@ -119,7 +119,8 @@ export default { 'shlv', 'shrv', 'sqrtv', - 'hypot' + 'hypot', + 'mdocumentation' ], ignorePaths: [ 'node_modules/**', diff --git a/rust/src/interfaces/napi_interface.rs b/rust/src/interfaces/napi_interface.rs index aede8e80..c005d6f2 100644 --- a/rust/src/interfaces/napi_interface.rs +++ b/rust/src/interfaces/napi_interface.rs @@ -735,7 +735,6 @@ mod tests { ..Default::default() }) .expect("expected a VM"); - assert!(!vm.inner.diagnostic_links); vm.with_diagnostic_links(true) .expect("expected the setting to update"); diff --git a/rust/src/interfaces/native_interface.rs b/rust/src/interfaces/native_interface.rs index 683ffd6c..64554c71 100644 --- a/rust/src/interfaces/native_interface.rs +++ b/rust/src/interfaces/native_interface.rs @@ -641,7 +641,6 @@ mod tests { let error = vm .load_internal("invalid source".to_string()) .expect_err("expected invalid source to fail"); - assert!(!error.to_string().contains("documentation:")); } #[test] diff --git a/rust/src/modules/vmerror/error.rs b/rust/src/modules/vmerror/error.rs index f215cde1..8e2661fe 100644 --- a/rust/src/modules/vmerror/error.rs +++ b/rust/src/modules/vmerror/error.rs @@ -103,7 +103,6 @@ impl VMError { VMError::SystemError(_) => "LVM500", } } - /// Returns the documentation URL for this error. #[cold] pub fn diagnostic_link(&self) -> String { @@ -113,13 +112,11 @@ impl VMError { ) } } - #[cfg(test)] mod tests { use super::VMError; use crate::modules::vmerror::config::set_thread_error_config; use smol_str::SmolStr; - fn all_errors() -> Vec { vec![ VMError::StackOverflow { ip: 1, limit: 2 }, @@ -165,7 +162,6 @@ mod tests { VMError::TickLimitExceeded, ] } - #[test] fn every_error_has_a_diagnostic_link_containing_its_code() { for error in all_errors() { @@ -179,7 +175,6 @@ mod tests { ); } } - #[test] fn formatted_error_contains_its_diagnostic_link() { set_thread_error_config(false, false, true, true); @@ -188,13 +183,11 @@ mod tests { let metadata_position = formatted.find("error type:").unwrap(); let documentation_position = formatted.find("documentation:").unwrap(); let hint_position = formatted.find("hint:").unwrap(); - assert!(formatted.contains(&format!("documentation: {}", error.diagnostic_link()))); assert!(formatted.contains("\x1b[36m├── \x1b[2;37mdocumentation:")); assert!(metadata_position < documentation_position); assert!(documentation_position < hint_position); } - #[test] fn formatted_system_error_contains_its_diagnostic_link() { set_thread_error_config(false, false, true, true); @@ -203,22 +196,18 @@ mod tests { let error_position = formatted.find("system failure").unwrap(); let documentation_position = formatted.find("documentation:").unwrap(); let hint_position = formatted.find("hint:").unwrap(); - assert!(formatted.contains(&error.diagnostic_link())); assert!(error_position < documentation_position); assert!(documentation_position < hint_position); } - #[test] fn diagnostic_link_is_rendered_when_hints_are_disabled() { set_thread_error_config(false, false, false, true); let error = VMError::StackOverflow { ip: 1, limit: 2 }; let formatted = error.to_string(); - assert!(formatted.contains(&error.diagnostic_link())); assert!(formatted.contains("documentation:")); } - #[test] fn diagnostic_link_is_rendered_before_backtrace() { set_thread_error_config(true, false, true, true); @@ -226,15 +215,12 @@ mod tests { let formatted = error.to_string(); let documentation_position = formatted.find("documentation:").unwrap(); let backtrace_position = formatted.find("internal backtrace:").unwrap(); - assert!(documentation_position < backtrace_position); } - #[test] fn diagnostic_link_can_be_disabled() { set_thread_error_config(false, false, true, false); let error = VMError::StackOverflow { ip: 1, limit: 2 }; - assert!(!error.to_string().contains("documentation:")); } } diff --git a/rust/src/types/error_options.rs b/rust/src/types/error_options.rs index 202ad519..be4e6c7c 100644 --- a/rust/src/types/error_options.rs +++ b/rust/src/types/error_options.rs @@ -25,11 +25,9 @@ impl Default for ErrorOptions { } } } - #[cfg(test)] mod tests { use super::ErrorOptions; - #[test] fn diagnostic_links_are_enabled_by_default() { assert!(ErrorOptions::default().diagnostic_links); From 8d6d8140412114dc4e420b0b28d5fd21c4bde2a1 Mon Sep 17 00:00:00 2001 From: Claycuy Date: Mon, 14 Sep 2026 09:31:00 +0800 Subject: [PATCH 06/10] chore: Update typing files --- ts/src/generated/CompileConfig.ts | 6 +- ts/src/generated/Instructions.ts | 132 +----------------- ts/src/generated/PrimitiveTypes.ts | 3 +- ts/src/generated/Value.ts | 17 +-- types/generated/Instructions.d.ts | 204 ++++++++++++++-------------- types/generated/PrimitiveTypes.d.ts | 2 +- 6 files changed, 107 insertions(+), 257 deletions(-) diff --git a/ts/src/generated/CompileConfig.ts b/ts/src/generated/CompileConfig.ts index 629980a1..cb564829 100644 --- a/ts/src/generated/CompileConfig.ts +++ b/ts/src/generated/CompileConfig.ts @@ -1,7 +1,3 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type CompileConfig = { - targetArch: number; - fileType: number; - path: string; -}; +export type CompileConfig = { targetArch: number, fileType: number, path: string, }; diff --git a/ts/src/generated/Instructions.ts b/ts/src/generated/Instructions.ts index a3d796f8..71228a68 100644 --- a/ts/src/generated/Instructions.ts +++ b/ts/src/generated/Instructions.ts @@ -2,134 +2,4 @@ import type { PrimitiveTypes } from './PrimitiveTypes.js'; import type { Value } from './Value.js'; -export type Instructions = - | { push_int16: number } - | { push_int32: number } - | { push_int64: number } - | { push_int128: number } - | { push_float16: number } - | { push_float32: number } - | { push_float64: number } - | { push_string: string } - | { push_array: any[] } - | { push_object: Record } - | { push_bool: boolean } - | 'push_null' - | 'push_undefined' - | 'push_na_n' - | { push: Value } - | { val: string } - | { val_idx: number } - | { set: string } - | { set_idx: number } - | { get: string } - | { get_idx: number } - | { add: PrimitiveTypes } - | { addv: PrimitiveTypes } - | { sub: PrimitiveTypes } - | { subv: PrimitiveTypes } - | { mul: PrimitiveTypes } - | { mulv: PrimitiveTypes } - | { div: PrimitiveTypes } - | { divv: PrimitiveTypes } - | { mod: PrimitiveTypes } - | { modv: PrimitiveTypes } - | { shl: PrimitiveTypes } - | { shr: PrimitiveTypes } - | { ror: PrimitiveTypes } - | { rol: PrimitiveTypes } - | { sin: PrimitiveTypes } - | { cos: PrimitiveTypes } - | { tan: PrimitiveTypes } - | { sinv: PrimitiveTypes } - | { cosv: PrimitiveTypes } - | { tanv: PrimitiveTypes } - | { asin: PrimitiveTypes } - | { acos: PrimitiveTypes } - | { atan: PrimitiveTypes } - | { atan2: PrimitiveTypes } - | { asinv: PrimitiveTypes } - | { acosv: PrimitiveTypes } - | { atanv: PrimitiveTypes } - | { atan2v: PrimitiveTypes } - | { sinh: PrimitiveTypes } - | { cosh: PrimitiveTypes } - | { tanh: PrimitiveTypes } - | { sinhv: PrimitiveTypes } - | { coshv: PrimitiveTypes } - | { tanhv: PrimitiveTypes } - | { asinh: PrimitiveTypes } - | { acosh: PrimitiveTypes } - | { atanh: PrimitiveTypes } - | { asinhv: PrimitiveTypes } - | { acoshv: PrimitiveTypes } - | { atanhv: PrimitiveTypes } - | { sqrt: PrimitiveTypes } - | { cbrt: PrimitiveTypes } - | { neg: PrimitiveTypes } - | { negv: PrimitiveTypes } - | { ln: PrimitiveTypes } - | { exp: PrimitiveTypes } - | { log2: PrimitiveTypes } - | { log10: PrimitiveTypes } - | { pow: PrimitiveTypes } - | { powi: PrimitiveTypes } - | { powf: PrimitiveTypes } - | { powv: PrimitiveTypes } - | { powiv: PrimitiveTypes } - | { powfv: PrimitiveTypes } - | { gt: PrimitiveTypes } - | { lt: PrimitiveTypes } - | { ge: PrimitiveTypes } - | { le: PrimitiveTypes } - | { eq: PrimitiveTypes } - | { neq: PrimitiveTypes } - | { dot: PrimitiveTypes } - | { cross: PrimitiveTypes } - | 'and' - | 'or' - | 'xor' - | 'not' - | 'print' - | 'println' - | 'stdout' - | 'stdoutln' - | 'stdin' - | 'clear_screen' - | { if_false: number } - | { jump: number } - | { inc: [string, PrimitiveTypes] } - | { inc_idx: [number, PrimitiveTypes] } - | { dec: [string, PrimitiveTypes] } - | { dec_idx: [number, PrimitiveTypes] } - | { call: [string, PrimitiveTypes] } - | { func: [string, number, number, number, string[]] } - | 'stop' - | 'return' - | { break: number } - | { access: string } - | 'access_index' - | 'to_string' - | 'to_short' - | 'to_integer' - | 'to_long' - | 'to_octa' - | 'to_half' - | 'to_float' - | 'to_double' - | { make_obj: number } - | { make_array: number } - | 'type_of' - | 'inspect_obj' - | 'inspect_arr' - | 'length' - | 'concat' - | 'dup' - | 'swap' - | { set_prop: string } - | { import: [string, number] } - | { export: string } - | { instantiate: [string, number] } - | 'nop' - | 'truncate' - | 'shrink'; +export type Instructions = { "push_int16": number } | { "push_int32": number } | { "push_int64": number } | { "push_int128": number } | { "push_float16": number } | { "push_float32": number } | { "push_float64": number } | { "push_string": string } | { "push_array": any[] } | { "push_object": Record } | { "push_bool": boolean } | "push_null" | "push_undefined" | "push_na_n" | { "push": Value } | { "val": string } | { "val_idx": number } | { "set": string } | { "set_idx": number } | { "get": string } | { "get_idx": number } | { "add": PrimitiveTypes } | { "addv": PrimitiveTypes } | { "sub": PrimitiveTypes } | { "subv": PrimitiveTypes } | { "mul": PrimitiveTypes } | { "mulv": PrimitiveTypes } | { "div": PrimitiveTypes } | { "divv": PrimitiveTypes } | { "mod": PrimitiveTypes } | { "modv": PrimitiveTypes } | { "shl": PrimitiveTypes } | { "shlv": PrimitiveTypes } | { "shr": PrimitiveTypes } | { "shrv": PrimitiveTypes } | { "ror": PrimitiveTypes } | { "rorv": PrimitiveTypes } | { "rol": PrimitiveTypes } | { "rolv": PrimitiveTypes } | { "sin": PrimitiveTypes } | { "cos": PrimitiveTypes } | { "tan": PrimitiveTypes } | { "sinv": PrimitiveTypes } | { "cosv": PrimitiveTypes } | { "tanv": PrimitiveTypes } | { "asin": PrimitiveTypes } | { "acos": PrimitiveTypes } | { "atan": PrimitiveTypes } | { "atan2": PrimitiveTypes } | { "asinv": PrimitiveTypes } | { "acosv": PrimitiveTypes } | { "atanv": PrimitiveTypes } | { "atan2v": PrimitiveTypes } | { "sinh": PrimitiveTypes } | { "cosh": PrimitiveTypes } | { "tanh": PrimitiveTypes } | { "sinhv": PrimitiveTypes } | { "coshv": PrimitiveTypes } | { "tanhv": PrimitiveTypes } | { "asinh": PrimitiveTypes } | { "acosh": PrimitiveTypes } | { "atanh": PrimitiveTypes } | { "asinhv": PrimitiveTypes } | { "acoshv": PrimitiveTypes } | { "atanhv": PrimitiveTypes } | { "sqrt": PrimitiveTypes } | { "sqrtv": PrimitiveTypes } | { "cbrt": PrimitiveTypes } | { "cbrtv": PrimitiveTypes } | { "neg": PrimitiveTypes } | { "negv": PrimitiveTypes } | { "ln": PrimitiveTypes } | { "lnv": PrimitiveTypes } | { "exp": PrimitiveTypes } | { "expv": PrimitiveTypes } | { "log2": PrimitiveTypes } | { "log2v": PrimitiveTypes } | { "log10": PrimitiveTypes } | { "log10v": PrimitiveTypes } | { "pow": PrimitiveTypes } | { "powi": PrimitiveTypes } | { "powf": PrimitiveTypes } | { "powv": PrimitiveTypes } | { "powiv": PrimitiveTypes } | { "powfv": PrimitiveTypes } | { "gt": PrimitiveTypes } | { "lt": PrimitiveTypes } | { "ge": PrimitiveTypes } | { "le": PrimitiveTypes } | { "eq": PrimitiveTypes } | { "neq": PrimitiveTypes } | { "dot": PrimitiveTypes } | { "cross": PrimitiveTypes } | { "normalize": PrimitiveTypes } | "and" | "or" | "xor" | "not" | "print" | "println" | "stdout" | "stdoutln" | "stdin" | "clear_screen" | { "if_false": number } | { "jump": number } | { "inc": [string, PrimitiveTypes] } | { "inc_idx": [number, PrimitiveTypes] } | { "dec": [string, PrimitiveTypes] } | { "dec_idx": [number, PrimitiveTypes] } | { "call": [string, PrimitiveTypes] } | { "func": [string, number, number, number, string[]] } | "stop" | "return" | { "break": number } | { "access": string } | "access_index" | "to_string" | "to_short" | "to_integer" | "to_long" | "to_octa" | "to_half" | "to_float" | "to_double" | { "make_obj": number } | { "make_array": number } | "type_of" | "inspect_obj" | "inspect_arr" | "length" | "concat" | "dup" | "swap" | { "set_prop": string } | { "import": [string, number] } | { "export": string } | { "instantiate": [string, number] } | "nop" | "truncate" | "shrink"; diff --git a/ts/src/generated/PrimitiveTypes.ts b/ts/src/generated/PrimitiveTypes.ts index cbeec870..764899b2 100644 --- a/ts/src/generated/PrimitiveTypes.ts +++ b/ts/src/generated/PrimitiveTypes.ts @@ -1,4 +1,3 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type PrimitiveTypes = - 'Sht' | 'Int' | 'Lng' | 'Oct' | 'Hlf' | 'Flt' | 'Dbl' | 'Str'; +export type PrimitiveTypes = "Sht" | "Int" | "Lng" | "Oct" | "Hlf" | "Flt" | "Dbl" | "Str"; diff --git a/ts/src/generated/Value.ts b/ts/src/generated/Value.ts index ca621643..c665ae83 100644 --- a/ts/src/generated/Value.ts +++ b/ts/src/generated/Value.ts @@ -1,18 +1,3 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type Value = - | number - | number - | number - | number - | number - | number - | number - | string - | any[] - | Record - | boolean - | null - | null - | null - | string; +export type Value = number | number | number | number | number | number | number | string | any[] | Record | boolean | null | null | null | string; diff --git a/types/generated/Instructions.d.ts b/types/generated/Instructions.d.ts index c8c1b6fb..6b35b83d 100644 --- a/types/generated/Instructions.d.ts +++ b/types/generated/Instructions.d.ts @@ -1,195 +1,195 @@ import type { PrimitiveTypes } from './PrimitiveTypes.js'; import type { Value } from './Value.js'; export type Instructions = { - "push_int16": number; + push_int16: number; } | { - "push_int32": number; + push_int32: number; } | { - "push_int64": number; + push_int64: number; } | { - "push_int128": number; + push_int128: number; } | { - "push_float16": number; + push_float16: number; } | { - "push_float32": number; + push_float32: number; } | { - "push_float64": number; + push_float64: number; } | { - "push_string": string; + push_string: string; } | { - "push_array": any[]; + push_array: any[]; } | { - "push_object": Record; + push_object: Record; } | { - "push_bool": boolean; -} | "push_null" | "push_undefined" | "push_na_n" | { - "push": Value; + push_bool: boolean; +} | 'push_null' | 'push_undefined' | 'push_na_n' | { + push: Value; } | { - "val": string; + val: string; } | { - "val_idx": number; + val_idx: number; } | { - "set": string; + set: string; } | { - "set_idx": number; + set_idx: number; } | { - "get": string; + get: string; } | { - "get_idx": number; + get_idx: number; } | { - "add": PrimitiveTypes; + add: PrimitiveTypes; } | { - "addv": PrimitiveTypes; + addv: PrimitiveTypes; } | { - "sub": PrimitiveTypes; + sub: PrimitiveTypes; } | { - "subv": PrimitiveTypes; + subv: PrimitiveTypes; } | { - "mul": PrimitiveTypes; + mul: PrimitiveTypes; } | { - "mulv": PrimitiveTypes; + mulv: PrimitiveTypes; } | { - "div": PrimitiveTypes; + div: PrimitiveTypes; } | { - "divv": PrimitiveTypes; + divv: PrimitiveTypes; } | { - "mod": PrimitiveTypes; + mod: PrimitiveTypes; } | { - "modv": PrimitiveTypes; + modv: PrimitiveTypes; } | { - "shl": PrimitiveTypes; + shl: PrimitiveTypes; } | { - "shr": PrimitiveTypes; + shr: PrimitiveTypes; } | { - "ror": PrimitiveTypes; + ror: PrimitiveTypes; } | { - "rol": PrimitiveTypes; + rol: PrimitiveTypes; } | { - "sin": PrimitiveTypes; + sin: PrimitiveTypes; } | { - "cos": PrimitiveTypes; + cos: PrimitiveTypes; } | { - "tan": PrimitiveTypes; + tan: PrimitiveTypes; } | { - "sinv": PrimitiveTypes; + sinv: PrimitiveTypes; } | { - "cosv": PrimitiveTypes; + cosv: PrimitiveTypes; } | { - "tanv": PrimitiveTypes; + tanv: PrimitiveTypes; } | { - "asin": PrimitiveTypes; + asin: PrimitiveTypes; } | { - "acos": PrimitiveTypes; + acos: PrimitiveTypes; } | { - "atan": PrimitiveTypes; + atan: PrimitiveTypes; } | { - "atan2": PrimitiveTypes; + atan2: PrimitiveTypes; } | { - "asinv": PrimitiveTypes; + asinv: PrimitiveTypes; } | { - "acosv": PrimitiveTypes; + acosv: PrimitiveTypes; } | { - "atanv": PrimitiveTypes; + atanv: PrimitiveTypes; } | { - "atan2v": PrimitiveTypes; + atan2v: PrimitiveTypes; } | { - "sinh": PrimitiveTypes; + sinh: PrimitiveTypes; } | { - "cosh": PrimitiveTypes; + cosh: PrimitiveTypes; } | { - "tanh": PrimitiveTypes; + tanh: PrimitiveTypes; } | { - "sinhv": PrimitiveTypes; + sinhv: PrimitiveTypes; } | { - "coshv": PrimitiveTypes; + coshv: PrimitiveTypes; } | { - "tanhv": PrimitiveTypes; + tanhv: PrimitiveTypes; } | { - "asinh": PrimitiveTypes; + asinh: PrimitiveTypes; } | { - "acosh": PrimitiveTypes; + acosh: PrimitiveTypes; } | { - "atanh": PrimitiveTypes; + atanh: PrimitiveTypes; } | { - "asinhv": PrimitiveTypes; + asinhv: PrimitiveTypes; } | { - "acoshv": PrimitiveTypes; + acoshv: PrimitiveTypes; } | { - "atanhv": PrimitiveTypes; + atanhv: PrimitiveTypes; } | { - "sqrt": PrimitiveTypes; + sqrt: PrimitiveTypes; } | { - "cbrt": PrimitiveTypes; + cbrt: PrimitiveTypes; } | { - "neg": PrimitiveTypes; + neg: PrimitiveTypes; } | { - "negv": PrimitiveTypes; + negv: PrimitiveTypes; } | { - "ln": PrimitiveTypes; + ln: PrimitiveTypes; } | { - "exp": PrimitiveTypes; + exp: PrimitiveTypes; } | { - "log2": PrimitiveTypes; + log2: PrimitiveTypes; } | { - "log10": PrimitiveTypes; + log10: PrimitiveTypes; } | { - "pow": PrimitiveTypes; + pow: PrimitiveTypes; } | { - "powi": PrimitiveTypes; + powi: PrimitiveTypes; } | { - "powf": PrimitiveTypes; + powf: PrimitiveTypes; } | { - "powv": PrimitiveTypes; + powv: PrimitiveTypes; } | { - "powiv": PrimitiveTypes; + powiv: PrimitiveTypes; } | { - "powfv": PrimitiveTypes; + powfv: PrimitiveTypes; } | { - "gt": PrimitiveTypes; + gt: PrimitiveTypes; } | { - "lt": PrimitiveTypes; + lt: PrimitiveTypes; } | { - "ge": PrimitiveTypes; + ge: PrimitiveTypes; } | { - "le": PrimitiveTypes; + le: PrimitiveTypes; } | { - "eq": PrimitiveTypes; + eq: PrimitiveTypes; } | { - "neq": PrimitiveTypes; + neq: PrimitiveTypes; } | { - "dot": PrimitiveTypes; + dot: PrimitiveTypes; } | { - "cross": PrimitiveTypes; -} | "and" | "or" | "xor" | "not" | "print" | "println" | "stdout" | "stdoutln" | "stdin" | "clear_screen" | { - "if_false": number; + cross: PrimitiveTypes; +} | 'and' | 'or' | 'xor' | 'not' | 'print' | 'println' | 'stdout' | 'stdoutln' | 'stdin' | 'clear_screen' | { + if_false: number; } | { - "jump": number; + jump: number; } | { - "inc": [string, PrimitiveTypes]; + inc: [string, PrimitiveTypes]; } | { - "inc_idx": [number, PrimitiveTypes]; + inc_idx: [number, PrimitiveTypes]; } | { - "dec": [string, PrimitiveTypes]; + dec: [string, PrimitiveTypes]; } | { - "dec_idx": [number, PrimitiveTypes]; + dec_idx: [number, PrimitiveTypes]; } | { - "call": [string, PrimitiveTypes]; + call: [string, PrimitiveTypes]; } | { - "func": [string, number, number, number, string[]]; -} | "stop" | "return" | { - "break": number; + func: [string, number, number, number, string[]]; +} | 'stop' | 'return' | { + break: number; } | { - "access": string; -} | "access_index" | "to_string" | "to_short" | "to_integer" | "to_long" | "to_octa" | "to_half" | "to_float" | "to_double" | { - "make_obj": number; + access: string; +} | 'access_index' | 'to_string' | 'to_short' | 'to_integer' | 'to_long' | 'to_octa' | 'to_half' | 'to_float' | 'to_double' | { + make_obj: number; } | { - "make_array": number; -} | "type_of" | "inspect_obj" | "inspect_arr" | "length" | "concat" | "dup" | "swap" | { - "set_prop": string; + make_array: number; +} | 'type_of' | 'inspect_obj' | 'inspect_arr' | 'length' | 'concat' | 'dup' | 'swap' | { + set_prop: string; } | { - "import": [string, number]; + import: [string, number]; } | { - "export": string; + export: string; } | { - "instantiate": [string, number]; -} | "nop" | "truncate" | "shrink"; + instantiate: [string, number]; +} | 'nop' | 'truncate' | 'shrink'; diff --git a/types/generated/PrimitiveTypes.d.ts b/types/generated/PrimitiveTypes.d.ts index aa31afbd..4e5b141f 100644 --- a/types/generated/PrimitiveTypes.d.ts +++ b/types/generated/PrimitiveTypes.d.ts @@ -1 +1 @@ -export type PrimitiveTypes = "Sht" | "Int" | "Lng" | "Oct" | "Hlf" | "Flt" | "Dbl" | "Str"; +export type PrimitiveTypes = 'Sht' | 'Int' | 'Lng' | 'Oct' | 'Hlf' | 'Flt' | 'Dbl' | 'Str'; From 735cec59c2756ebfa948ff5a99a7df9e7926c0d0 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 10:42:59 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=F0=9F=93=9D=20CodeRabbit=20Chat:=20Add?= =?UTF-8?q?=20diagnosticLinks=20to=20TypeScript=20ErrorOptions=20defaults?= =?UTF-8?q?=20(#587)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- ts/src/index.ts | 7 +- types/generated/Instructions.d.ts | 226 +++++++++++++++------------- types/generated/PrimitiveTypes.d.ts | 2 +- types/utils/isMusl.d.ts | 2 +- 4 files changed, 132 insertions(+), 105 deletions(-) diff --git a/ts/src/index.ts b/ts/src/index.ts index b1918cbb..6ea80703 100644 --- a/ts/src/index.ts +++ b/ts/src/index.ts @@ -57,7 +57,12 @@ export class LightVM { private static readonly DEFAULTS: VMConfig = { caps: [Capability.Observe], runtimeConfig: { nightly: false }, - errorOptions: { backtrace: false, explain: false, hint: true }, + errorOptions: { + backtrace: false, + explain: false, + hint: true, + diagnosticLinks: true, + }, securityConfig: { maxIo: 100, maxImport: 3, diff --git a/types/generated/Instructions.d.ts b/types/generated/Instructions.d.ts index 6b35b83d..3fe32a11 100644 --- a/types/generated/Instructions.d.ts +++ b/types/generated/Instructions.d.ts @@ -1,195 +1,217 @@ import type { PrimitiveTypes } from './PrimitiveTypes.js'; import type { Value } from './Value.js'; export type Instructions = { - push_int16: number; + "push_int16": number; } | { - push_int32: number; + "push_int32": number; } | { - push_int64: number; + "push_int64": number; } | { - push_int128: number; + "push_int128": number; } | { - push_float16: number; + "push_float16": number; } | { - push_float32: number; + "push_float32": number; } | { - push_float64: number; + "push_float64": number; } | { - push_string: string; + "push_string": string; } | { - push_array: any[]; + "push_array": any[]; } | { - push_object: Record; + "push_object": Record; } | { - push_bool: boolean; -} | 'push_null' | 'push_undefined' | 'push_na_n' | { - push: Value; + "push_bool": boolean; +} | "push_null" | "push_undefined" | "push_na_n" | { + "push": Value; } | { - val: string; + "val": string; } | { - val_idx: number; + "val_idx": number; } | { - set: string; + "set": string; } | { - set_idx: number; + "set_idx": number; } | { - get: string; + "get": string; } | { - get_idx: number; + "get_idx": number; } | { - add: PrimitiveTypes; + "add": PrimitiveTypes; } | { - addv: PrimitiveTypes; + "addv": PrimitiveTypes; } | { - sub: PrimitiveTypes; + "sub": PrimitiveTypes; } | { - subv: PrimitiveTypes; + "subv": PrimitiveTypes; } | { - mul: PrimitiveTypes; + "mul": PrimitiveTypes; } | { - mulv: PrimitiveTypes; + "mulv": PrimitiveTypes; } | { - div: PrimitiveTypes; + "div": PrimitiveTypes; } | { - divv: PrimitiveTypes; + "divv": PrimitiveTypes; } | { - mod: PrimitiveTypes; + "mod": PrimitiveTypes; } | { - modv: PrimitiveTypes; + "modv": PrimitiveTypes; } | { - shl: PrimitiveTypes; + "shl": PrimitiveTypes; } | { - shr: PrimitiveTypes; + "shlv": PrimitiveTypes; } | { - ror: PrimitiveTypes; + "shr": PrimitiveTypes; } | { - rol: PrimitiveTypes; + "shrv": PrimitiveTypes; } | { - sin: PrimitiveTypes; + "ror": PrimitiveTypes; } | { - cos: PrimitiveTypes; + "rorv": PrimitiveTypes; } | { - tan: PrimitiveTypes; + "rol": PrimitiveTypes; } | { - sinv: PrimitiveTypes; + "rolv": PrimitiveTypes; } | { - cosv: PrimitiveTypes; + "sin": PrimitiveTypes; } | { - tanv: PrimitiveTypes; + "cos": PrimitiveTypes; } | { - asin: PrimitiveTypes; + "tan": PrimitiveTypes; } | { - acos: PrimitiveTypes; + "sinv": PrimitiveTypes; } | { - atan: PrimitiveTypes; + "cosv": PrimitiveTypes; } | { - atan2: PrimitiveTypes; + "tanv": PrimitiveTypes; } | { - asinv: PrimitiveTypes; + "asin": PrimitiveTypes; } | { - acosv: PrimitiveTypes; + "acos": PrimitiveTypes; } | { - atanv: PrimitiveTypes; + "atan": PrimitiveTypes; } | { - atan2v: PrimitiveTypes; + "atan2": PrimitiveTypes; } | { - sinh: PrimitiveTypes; + "asinv": PrimitiveTypes; } | { - cosh: PrimitiveTypes; + "acosv": PrimitiveTypes; } | { - tanh: PrimitiveTypes; + "atanv": PrimitiveTypes; } | { - sinhv: PrimitiveTypes; + "atan2v": PrimitiveTypes; } | { - coshv: PrimitiveTypes; + "sinh": PrimitiveTypes; } | { - tanhv: PrimitiveTypes; + "cosh": PrimitiveTypes; } | { - asinh: PrimitiveTypes; + "tanh": PrimitiveTypes; } | { - acosh: PrimitiveTypes; + "sinhv": PrimitiveTypes; } | { - atanh: PrimitiveTypes; + "coshv": PrimitiveTypes; } | { - asinhv: PrimitiveTypes; + "tanhv": PrimitiveTypes; } | { - acoshv: PrimitiveTypes; + "asinh": PrimitiveTypes; } | { - atanhv: PrimitiveTypes; + "acosh": PrimitiveTypes; } | { - sqrt: PrimitiveTypes; + "atanh": PrimitiveTypes; } | { - cbrt: PrimitiveTypes; + "asinhv": PrimitiveTypes; } | { - neg: PrimitiveTypes; + "acoshv": PrimitiveTypes; } | { - negv: PrimitiveTypes; + "atanhv": PrimitiveTypes; } | { - ln: PrimitiveTypes; + "sqrt": PrimitiveTypes; } | { - exp: PrimitiveTypes; + "sqrtv": PrimitiveTypes; } | { - log2: PrimitiveTypes; + "cbrt": PrimitiveTypes; } | { - log10: PrimitiveTypes; + "cbrtv": PrimitiveTypes; } | { - pow: PrimitiveTypes; + "neg": PrimitiveTypes; } | { - powi: PrimitiveTypes; + "negv": PrimitiveTypes; } | { - powf: PrimitiveTypes; + "ln": PrimitiveTypes; } | { - powv: PrimitiveTypes; + "lnv": PrimitiveTypes; } | { - powiv: PrimitiveTypes; + "exp": PrimitiveTypes; } | { - powfv: PrimitiveTypes; + "expv": PrimitiveTypes; } | { - gt: PrimitiveTypes; + "log2": PrimitiveTypes; } | { - lt: PrimitiveTypes; + "log2v": PrimitiveTypes; } | { - ge: PrimitiveTypes; + "log10": PrimitiveTypes; } | { - le: PrimitiveTypes; + "log10v": PrimitiveTypes; } | { - eq: PrimitiveTypes; + "pow": PrimitiveTypes; } | { - neq: PrimitiveTypes; + "powi": PrimitiveTypes; } | { - dot: PrimitiveTypes; + "powf": PrimitiveTypes; } | { - cross: PrimitiveTypes; -} | 'and' | 'or' | 'xor' | 'not' | 'print' | 'println' | 'stdout' | 'stdoutln' | 'stdin' | 'clear_screen' | { - if_false: number; + "powv": PrimitiveTypes; } | { - jump: number; + "powiv": PrimitiveTypes; } | { - inc: [string, PrimitiveTypes]; + "powfv": PrimitiveTypes; } | { - inc_idx: [number, PrimitiveTypes]; + "gt": PrimitiveTypes; } | { - dec: [string, PrimitiveTypes]; + "lt": PrimitiveTypes; } | { - dec_idx: [number, PrimitiveTypes]; + "ge": PrimitiveTypes; } | { - call: [string, PrimitiveTypes]; + "le": PrimitiveTypes; } | { - func: [string, number, number, number, string[]]; -} | 'stop' | 'return' | { - break: number; + "eq": PrimitiveTypes; } | { - access: string; -} | 'access_index' | 'to_string' | 'to_short' | 'to_integer' | 'to_long' | 'to_octa' | 'to_half' | 'to_float' | 'to_double' | { - make_obj: number; + "neq": PrimitiveTypes; } | { - make_array: number; -} | 'type_of' | 'inspect_obj' | 'inspect_arr' | 'length' | 'concat' | 'dup' | 'swap' | { - set_prop: string; + "dot": PrimitiveTypes; } | { - import: [string, number]; + "cross": PrimitiveTypes; } | { - export: string; + "normalize": PrimitiveTypes; +} | "and" | "or" | "xor" | "not" | "print" | "println" | "stdout" | "stdoutln" | "stdin" | "clear_screen" | { + "if_false": number; } | { - instantiate: [string, number]; -} | 'nop' | 'truncate' | 'shrink'; + "jump": number; +} | { + "inc": [string, PrimitiveTypes]; +} | { + "inc_idx": [number, PrimitiveTypes]; +} | { + "dec": [string, PrimitiveTypes]; +} | { + "dec_idx": [number, PrimitiveTypes]; +} | { + "call": [string, PrimitiveTypes]; +} | { + "func": [string, number, number, number, string[]]; +} | "stop" | "return" | { + "break": number; +} | { + "access": string; +} | "access_index" | "to_string" | "to_short" | "to_integer" | "to_long" | "to_octa" | "to_half" | "to_float" | "to_double" | { + "make_obj": number; +} | { + "make_array": number; +} | "type_of" | "inspect_obj" | "inspect_arr" | "length" | "concat" | "dup" | "swap" | { + "set_prop": string; +} | { + "import": [string, number]; +} | { + "export": string; +} | { + "instantiate": [string, number]; +} | "nop" | "truncate" | "shrink"; diff --git a/types/generated/PrimitiveTypes.d.ts b/types/generated/PrimitiveTypes.d.ts index 4e5b141f..aa31afbd 100644 --- a/types/generated/PrimitiveTypes.d.ts +++ b/types/generated/PrimitiveTypes.d.ts @@ -1 +1 @@ -export type PrimitiveTypes = 'Sht' | 'Int' | 'Lng' | 'Oct' | 'Hlf' | 'Flt' | 'Dbl' | 'Str'; +export type PrimitiveTypes = "Sht" | "Int" | "Lng" | "Oct" | "Hlf" | "Flt" | "Dbl" | "Str"; diff --git a/types/utils/isMusl.d.ts b/types/utils/isMusl.d.ts index 9ede6fb5..3156968c 100644 --- a/types/utils/isMusl.d.ts +++ b/types/utils/isMusl.d.ts @@ -7,4 +7,4 @@ * * http://www.apache.org/licenses/LICENSE-2.0 */ -export declare function isMusl(reportProvider?: NodeJS.ProcessReport): boolean; +export declare function isMusl(reportProvider?: any): any; From 925fef7135da58bada9573c502b8a8227c04b526 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 11:03:47 +0800 Subject: [PATCH 08/10] feat: Add diagnostic links to generated ErrorOptions types (#588) Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- ts/src/generated/ErrorOptions.ts | 1 + types/generated/ErrorOptions.d.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/ts/src/generated/ErrorOptions.ts b/ts/src/generated/ErrorOptions.ts index 491974ad..62222755 100644 --- a/ts/src/generated/ErrorOptions.ts +++ b/ts/src/generated/ErrorOptions.ts @@ -4,4 +4,5 @@ export type ErrorOptions = { backtrace: boolean | null; explain: boolean | null; hint: boolean | null; + diagnosticLinks: boolean | null; }; diff --git a/types/generated/ErrorOptions.d.ts b/types/generated/ErrorOptions.d.ts index 0a236f38..c4ca04a6 100644 --- a/types/generated/ErrorOptions.d.ts +++ b/types/generated/ErrorOptions.d.ts @@ -2,4 +2,5 @@ export type ErrorOptions = { backtrace: boolean | null; explain: boolean | null; hint: boolean | null; + diagnosticLinks: boolean | null; }; From 1c1a8819902dcc3cac0ace20da334e492a996aa0 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 18:22:19 +0800 Subject: [PATCH 09/10] =?UTF-8?q?=F0=9F=93=9D=20CodeRabbit=20Chat:=20Docum?= =?UTF-8?q?ent=20diagnostic=20links=20and=20configuration=20APIs=20(#602)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- docs/en/get-started/quick-usage.md | 47 +++++++++++++++++++++ docs/examples/getStarted/builderPattern.ts | 3 +- docs/examples/getStarted/builder_pattern.rs | 5 ++- docs/examples/getStarted/objectPattern.ts | 1 + docs/examples/getStarted/object_pattern.rs | 5 ++- ts/src/index.ts | 2 + types/index.d.ts | 1 + 7 files changed, 59 insertions(+), 5 deletions(-) diff --git a/docs/en/get-started/quick-usage.md b/docs/en/get-started/quick-usage.md index 4953e5c3..8e60cbd9 100644 --- a/docs/en/get-started/quick-usage.md +++ b/docs/en/get-started/quick-usage.md @@ -24,6 +24,53 @@ For Rust projects, configure `VmConfig` before creating the VM. ::: +## Diagnostic links + +Formatted VM errors include a `documentation:` metadata row by default. Its URL is derived from the error's `LVM` code and points to the matching page in the [error-code reference](/api-reference/error-codes/lvm001-code). + +Disable the row through the constructor configuration or the fluent API: + +::: code-group + +```rust [Native configuration] +let vm = LightVM::new(VmConfig { + error_options: Some(ErrorOptions { + diagnostic_links: false, + ..Default::default() + }), + ..Default::default() +}); + +let vm = LightVM::new(VmConfig::default()) + .with_diagnostic_links(false); +``` + +```ts [Node.js] +const vm = new LightVM({ + errorOptions: { + backtrace: false, + explain: false, + hint: true, + diagnosticLinks: false, + }, +}); + +vm.withDiagnosticLinks(false); +``` + +```ts [WASM] +const vm = new LightVM({ + caps: [], + errorOptions: { diagnosticLinks: false }, +}); + +vm.withDiagnosticLinks(false); +``` + +::: + +The same setting is retained by `tools()` and applies to errors from tool operations, including bytecode optimization. + ## Expected result You have a configured VM instance ready to load bytecode. Continue with the [Run Method](/api-reference/method-functions/run-method), or review [Capabilities](/api-reference/capabilities) before granting access. diff --git a/docs/examples/getStarted/builderPattern.ts b/docs/examples/getStarted/builderPattern.ts index 8712e874..c21e4bb8 100644 --- a/docs/examples/getStarted/builderPattern.ts +++ b/docs/examples/getStarted/builderPattern.ts @@ -14,6 +14,7 @@ const vm = new LightVM({ caps: [Capability.Observe, Capability.Control] }) .withNightly(false) // Allow nightly features (default: false) .withBacktrace(false) // Display backtrace details in error messages (default: false) .withExplain(false) // Display a more detailed hint in the error message (default: false) - .withHint(true); // Display a hint on error messages (default: true) + .withHint(true) // Display a hint on error messages (default: true) + .withDiagnosticLinks(false); // Hide links to error-code documentation (default: true) const tools = vm.tools(); diff --git a/docs/examples/getStarted/builder_pattern.rs b/docs/examples/getStarted/builder_pattern.rs index 31ef27d3..9ef97d0b 100644 --- a/docs/examples/getStarted/builder_pattern.rs +++ b/docs/examples/getStarted/builder_pattern.rs @@ -19,7 +19,8 @@ fn main() { .with_nightly(false) // Allow nightly features (default: false) .with_backtrace(false) // Display backtrace details in error messages (default: false) .with_explain(false) // Display a more detailed hint in the error message (default: false) - .with_hint(true); // Display a hint on error messages (default: true) + .with_hint(true) // Display a hint on error messages (default: true) + .with_diagnostic_links(false); // Hide links to error-code documentation (default: true) let tools = vm.tools(); -} \ No newline at end of file +} diff --git a/docs/examples/getStarted/objectPattern.ts b/docs/examples/getStarted/objectPattern.ts index 87c3a126..b7a3464a 100644 --- a/docs/examples/getStarted/objectPattern.ts +++ b/docs/examples/getStarted/objectPattern.ts @@ -9,6 +9,7 @@ const vm = new LightVM({ backtrace: false, // Display backtrace details in error messages (default: false) explain: false, // Display a more detailed hint in the error message (default: false) hint: true, // Display a hint on error messages (default: true) + diagnosticLinks: false, // Hide links to error-code documentation (default: true) }, securityConfig: { maxIo: 100, // Maximum number of I/O operations allowed (default: 100) diff --git a/docs/examples/getStarted/object_pattern.rs b/docs/examples/getStarted/object_pattern.rs index f9b291e4..523bf2e8 100644 --- a/docs/examples/getStarted/object_pattern.rs +++ b/docs/examples/getStarted/object_pattern.rs @@ -17,7 +17,8 @@ fn main() { error_options: Some(ErrorOptions { backtrace: false, // Display backtrace details in error messages (default: false) explain: false, // Display a more detailed hint in the error message (default: false) - hint: true // Display a hint on error messages (default: true) + hint: true, // Display a hint on error messages (default: true) + diagnostic_links: false // Hide links to error-code documentation (default: true) }), security_config: Some(SecurityConfig { max_io: 100, // Maximum number of I/O operations allowed (default: 100) @@ -34,4 +35,4 @@ fn main() { }); let tools = vm.tools(); -} \ No newline at end of file +} diff --git a/ts/src/index.ts b/ts/src/index.ts index 6ea80703..3f0a5db2 100644 --- a/ts/src/index.ts +++ b/ts/src/index.ts @@ -169,6 +169,8 @@ export class LightVM { withExplain = (en: boolean) => this.updateConfig('errorOptions', 'explain', en); withHint = (en: boolean) => this.updateConfig('errorOptions', 'hint', en); + withDiagnosticLinks = (en: boolean) => + this.updateConfig('errorOptions', 'diagnosticLinks', en); info() { return formatInfoVM(this.wrap(() => this.instance.info())); diff --git a/types/index.d.ts b/types/index.d.ts index 52ca9319..5864adba 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -72,6 +72,7 @@ export declare class LightVM { withBacktrace: (en: boolean) => this; withExplain: (en: boolean) => this; withHint: (en: boolean) => this; + withDiagnosticLinks: (en: boolean) => this; info(): string; load(source: Instructions[] | string): this; run(options?: any): any; From ff138af2af767c168a7da2c0584670e46cf1fba5 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 18:40:23 +0800 Subject: [PATCH 10/10] =?UTF-8?q?=F0=9F=93=9D=20CodeRabbit=20Chat:=20Synch?= =?UTF-8?q?ronize=20Indonesian=20Quick=20Usage=20Documentation=20with=20En?= =?UTF-8?q?glish=20Structure=20(#603)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- docs/id/get-started/quick-usage.md | 47 ++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/docs/id/get-started/quick-usage.md b/docs/id/get-started/quick-usage.md index 4cd0ae2d..8c6de527 100644 --- a/docs/id/get-started/quick-usage.md +++ b/docs/id/get-started/quick-usage.md @@ -24,6 +24,53 @@ Untuk proyek Rust, konfigurasikan `VmConfig` sebelum membuat VM. ::: +## Tautan diagnostik + +Error VM yang diformat menyertakan baris metadata `documentation:` secara default. URL-nya berasal dari kode `LVM` error dan mengarah ke halaman yang sesuai dalam [referensi kode error](/id/api-reference/error-codes/lvm001-code). + +Nonaktifkan baris tersebut melalui konfigurasi konstruktor atau API fluent: + +::: code-group + +```rust [Native configuration] +let vm = LightVM::new(VmConfig { + error_options: Some(ErrorOptions { + diagnostic_links: false, + ..Default::default() + }), + ..Default::default() +}); + +let vm = LightVM::new(VmConfig::default()) + .with_diagnostic_links(false); +``` + +```ts [Node.js] +const vm = new LightVM({ + errorOptions: { + backtrace: false, + explain: false, + hint: true, + diagnosticLinks: false, + }, +}); + +vm.withDiagnosticLinks(false); +``` + +```ts [WASM] +const vm = new LightVM({ + caps: [], + errorOptions: { diagnosticLinks: false }, +}); + +vm.withDiagnosticLinks(false); +``` + +::: + +Pengaturan yang sama dipertahankan oleh `tools()` dan berlaku untuk error dari operasi alat, termasuk optimasi bytecode. + ## Hasil yang diharapkan Anda memiliki instance VM terkonfigurasi yang siap memuat bytecode. Lanjutkan ke [Metode Run](/id/api-reference/method-functions/run-method), atau tinjau [Kapabilitas](/id/api-reference/capabilities) sebelum memberikan akses.