fix: 异常兜底路径经 create_from_text 恢复错误类型(不塌缩普通 Error)
This commit is contained in:
@@ -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`
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user