You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何跨浏览器识别抛出错误的匿名Function实例对应的代码来源

可行跨浏览器解决方案

方案1:使用sourceURL标记每个玩家的函数(推荐)

这是目前兼容性最好、实现成本最低的方案,原理是通过JS内置的源映射注释为每个Function实例分配唯一标识,所有主流浏览器都会在错误栈、window.onerror回调的source参数中携带该标识,不会影响原有行号的获取。
实现步骤:

  • 生成玩家函数时,在代码末尾追加唯一的sourceURL注释,标识中携带玩家ID/函数ID:
// 示例:玩家ID为123的代码
const playerCode = `// 玩家提交的原始代码
const a = 1;
console.log(x);
//# sourceURL=player-fn-123.js`;
const playerFn = new Function(playerCode);
  • 在window.onerror回调中直接从source参数提取标识即可判断归属:
window.onerror = function(message, source, lineno, colno, error) { 
  // source会返回你设置的"player-fn-123.js",提取123即可拿到对应玩家ID
  const playerId = source.match(/player-fn-(\d+)\.js/)?.[1];
  // lineno还是原始错误行号,不受影响
}

该方案在Chrome、Firefox、Safari等所有主流浏览器中均生效,不需要解析错误栈,和你现有获取行号的逻辑完全兼容。

方案2:使用闭包绑定上下文(备选)

如果你不能修改玩家提交的代码内容,可以为每个玩家函数生成一个独立的闭包包装器,在闭包内存储对应的玩家ID,当错误触发时,直接给原始错误对象挂载自定义标识即可:

function wrapPlayerFn(fn, playerId) {
  return function() {
    try {
      return fn.apply(this, arguments);
    } catch (e) {
      // 给错误对象挂载自定义属性
      e._playerId = playerId;
      // 直接抛出原始错误,不要重新封装Error对象,避免修改行号
      throw e;
    }
  }
}

之后在window.onerror回调中直接读取error._playerId即可,该操作不会修改原始错误的行号信息,Chrome、Firefox均兼容。

内容的提问来源于stack exchange,提问作者Gillespie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 17:54:03