fix: 异常兜底路径经 create_from_text 恢复错误类型(不塌缩普通 Error)

This commit is contained in:
爱特每羊队
2026-08-10 20:19:51 +08:00
parent e8506e6f29
commit 717e927057
8 changed files with 65 additions and 59 deletions
+3 -23
View File
@@ -155,31 +155,11 @@ pub(crate) fn invoke_native_callback<H: VmHost>(
Ok(value) => NativeResult::Ok(value),
Err(err) => match vm.take_uncaught_value() {
Some(original) => NativeResult::Err(original),
None => NativeResult::Err(callback_error_from_text(vm, &err)),
None => NativeResult::Err(crate::error::create_from_text(vm, &err)),
},
}
}
fn callback_error_from_text<H: VmHost>(vm: &mut H, err: &str) -> JsValue {
let err = err.strip_prefix("uncaught ").unwrap_or(err);
if let Some(msg) = err.strip_prefix("TypeError: ") {
return crate::error::create_type_error(vm, msg);
}
if let Some(msg) = err.strip_prefix("ReferenceError: ") {
return crate::error::create_reference_error(vm, msg);
}
if let Some(msg) = err.strip_prefix("RangeError: ") {
return crate::error::create_range_error(vm, msg);
}
if let Some(msg) = err.strip_prefix("SyntaxError: ") {
return crate::error::create_syntax_error(vm, msg);
}
if let Some(msg) = err.strip_prefix("Error: ") {
return crate::error::create_error(vm, msg);
}
crate::error::create_error(vm, err)
}
fn unexpected_tail_call_error<H: VmHost>(vm: &mut H) -> NativeResult {
NativeResult::Err(crate::error::create_type_error(vm, "unexpected tail call in array callback"))
}
@@ -412,9 +392,9 @@ pub fn array_from<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
NativeResult::Ok(JsValue::from_js_object(a_ptr))
}
/// 引擎调用边界抛出的错误恢复为原始异常值(透传),否则按错误文本构造普通错误。
/// 引擎调用边界抛出的错误恢复为原始异常值(透传),否则按错误文本构造对应 kind 的错误。
fn from_engine_error<H: VmHost>(vm: &mut H, err: &str) -> JsValue {
vm.take_uncaught_value().unwrap_or_else(|| callback_error_from_text(vm, err))
vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_from_text(vm, err))
}
/// 按构造函数 C 构造 Array.from 的结果对象:C 可构造时以 C.prototype 分配 `this`
+26
View File
@@ -65,6 +65,32 @@ pub fn create_error<H: VmHost>(host: &mut H, msg: &str) -> JsValue {
create_kind_error(host, "Error", msg)
}
/// 从错误文本(形如 `TypeError: msg` / `ReferenceError: msg`)解析类型前缀并创建
/// 对应 kind 的错误对象;无前缀时创建普通 Error。
///
/// # 使用场景
/// 异常传播链中错误对象被降级为文本(error_text 输出、`last_uncaught_value` 被
/// 嵌套覆盖后的兜底路径)时,据此恢复错误类型,避免全部塌缩成普通 Error。
pub fn create_from_text<H: VmHost>(host: &mut H, text: &str) -> JsValue {
let text = text.strip_prefix("uncaught ").unwrap_or(text);
for (kind, prefix) in [
("TypeError", "TypeError: "),
("ReferenceError", "ReferenceError: "),
("RangeError", "RangeError: "),
("SyntaxError", "SyntaxError: "),
("URIError", "URIError: "),
("EvalError", "EvalError: "),
] {
if let Some(msg) = text.strip_prefix(prefix) {
return create_kind_error(host, kind, msg);
}
}
if let Some(msg) = text.strip_prefix("Error: ") {
return create_kind_error(host, "Error", msg);
}
create_error(host, text)
}
/// 创建一个带指定 message 的 ReferenceError 对象。
pub fn create_reference_error<H: VmHost>(host: &mut H, msg: &str) -> JsValue {
create_kind_error(host, "ReferenceError", msg)