JS错误捕获

JS错误捕获js代码运行时,希望能捕获异常错误,上报后台监控,及时修复bug,那么如何捕获错误?下面我们来看下有哪些错误。 Script error. 跨域脚本,为了防止信息泄露,不会展示语法错误具体信息,只会展示 Script error. message:错误信息(字符串)。可用于HT…

js代码运行时,希望能捕获异常错误,上报后台监控,及时修复bug,那么如何捕获错误?下面我们来看下有哪些错误。

语法错误

同步错误

window.addEventListener('error', ()=>{
  console.log('addEventListener')
}, true);

window.addEventListener("unhandledrejection", function(e) {
    console.log('unhandledrejection')
}, true);

throw new Error();

// "addEventListener"

异步错误

window.addEventListener('error', ()=>{
  console.log('addEventListener')
}, true);

window.addEventListener("unhandledrejection", function(e) {
    console.log('unhandledrejection')
}, true);

setTimeout(()=>{
  throw new Error();
}, 10)

// "addEventListener"

资源错误(img、script、object等)

// 资源加载前,必须先监听错误事件
window.addEventListener('error', ()=>{
  console.log('addEventListener')
}, true);

window.addEventListener("unhandledrejection", function(e) {
    console.log('unhandledrejection')
}, true);

<img src="../404.png" />
<script src="../404.png"></script>

// "addEventListener"
// "addEventListener"

console.error错误

var consoleError = window.console.error;
window.console.error = function () {
    console.log('console')
    consoleError && consoleError.apply(window, arguments); 
};
console.error('error')

// "console"
// "error"

js跨域错误

// 跨域错误默认提示 Script error
window.addEventListener('error', ()=>{
  console.log('addEventListener')
}, true);

window.addEventListener("unhandledrejection", function(e) {
    console.log('unhandledrejection')
}, true);

// 客户端添加crossorigin属性
// 服务端添加Access-Control-Allow-Origin: *
// 否则只提示Script error,无法获取具体错误信息
<script src="https://dss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/static/protocol/https/jquery/jquery-1.10.2.min_65682a2.js"></script>

// "addEventListener"

promise错误

window.addEventListener('error', ()=>{
  console.log('addEventListener')
}, true);

window.addEventListener("unhandledrejection", function(e) {
    console.log('unhandledrejection')
}, true);

new Promise((resolve, reject)=>{
  throw new Error();
})

new Promise((resolve, reject)=>{
  resolve('')
})
.then((data)=>{
  throw new Error();
})

new Promise((resolve, reject)=>{
  throw new Error();
})
.catch((err)=>{
  console.error(err)
})

// [object Error] { ... }
// "unhandledrejection"
// "unhandledrejection"

async/await错误

window.addEventListener('error', (e)=>{
  console.log('addEventListener')
}, true);

window.addEventListener("unhandledrejection", function(e) {
    console.log('unhandledrejection')
}, true);

async function compute () {
    let a = 1;
    let b = await a + 2;

    throw new Error('async error')
}

compute()

// "unhandledrejection"

genrator错误

window.addEventListener('error', (e)=>{
  console.log('addEventListener')
}, true);

window.addEventListener("unhandledrejection", function(e) {
    console.log('unhandledrejection')
}, true);

// gennerator
function* F() {
  throw new Error("gennerator-throw在函数体外抛出的错误")
  yield 1;
  return "gennerator-value";
}

var f = F();

f.next();

// "addEventListener"

iframe错误

var frames = window.frames;
for (var i = 0; i < frames.length; i++) { 
  frames[i].addEventListener('error', (e)=>{
    console.log('addEventListener')
    console.log(e)
  }, true);

  frames[i].addEventListener("unhandledrejection", function(e) {
      console.log('unhandledrejection')
  }, true);
}

请求错误(XMLHttpRequest、fetch)

window.addEventListener('error', (e)=>{
  console.log('addEventListener')
  console.log(e)
}, true);

window.addEventListener("unhandledrejection", function(e) {
    console.log('unhandledrejection')
  console.log(e)
}, true);

// 请求返回错误
fetch('http://example.com/movies.json')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(myJson);
  });

// 无效请求
fetch('http://example.com/404.json')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(myJson);
  });

const xmlhttp = new XMLHttpRequest();

xmlhttp.onreadystatechange=state_Change;
xmlhttp.open("GET", 'http://127.0.0.1:8000/',true);
xmlhttp.send(null);

function state_Change(){
  if (xmlhttp.readyState == 4){// 4 = "loaded"
    if (xmlhttp.status == 200){// 200 = "OK"
      throw new Error('error')
    }else{
      console.log("Problem retrieving XML data:" + xmlhttp.statusText);
    }
  }
}

// fetch: "unhandledrejection"
// fetch: "unhandledrejection"
// xmlhttp: "addEventListener"

错误类型

Error

代码运行时的错误,除了 Error 这个对象,一些内置 错误类 在异常时返回,如SyntaxErrorEvalError 、 RangeError 、 ReferenceError 、 TypeError 等,具体信息Error

image.png

Script error.

跨域脚本,为了防止信息泄露,不会展示语法错误具体信息,只会展示 Script error.

可以先解决跨域:

  • 客户端script标签添加 crossorigin="anonymous"
  • 服务端响应header添加 Access-Control-Allow-Origin: *

或者使用 try/catch 捕获运行方法的错误信息

SyntaxError

语法错误是无法被捕获的,因为语法错误脚本不会放入任务队列,不会继续执行这段脚本,所以也不会有事件冒泡,这个是要在开发阶段就要防范,但是使用 eval 执行却可以捕获到错误信息

try {
  eval('hoo bar');
} catch (e) {
  console.log(e instanceof SyntaxError); // true
  console.log(e.message);                // "missing ; before statement"
  console.log(e.name);                   // "SyntaxError"
  console.log(e.fileName);               // "Scratchpad/1"
  console.log(e.lineNumber);             // 1
  console.log(e.columnNumber);           // 4
  console.log(e.stack);                  // "@Scratchpad/1:2:3\n"
}

DOMException

Web API 访问和调用时错误,API报错会设置错误name,如 SyntaxError 、 NotFoundError 等,具体信息DOMException

image.png

错误事件

error

window.onerror 和 window.addEventListener('error') 是基本一样的,但是 onerror 无法捕获资源加载失败,关于onerror浏览器兼容性可以看这篇文章

// useCapture 需要设置 true
// 事件冒泡
window.addEventListener('error', (e) => {
  console.log(e)
  console.log(e.message)
  console.log(e.source)
  console.log(e.lineno)
  console.log(e.colno)
  console.log(e.error)
  // 禁止默认错误提示
  e.preventDefault();
}, true);
  • message:错误信息(字符串)。可用于HTML onerror=””处理程序中的event。
  • source:发生错误的脚本URL(字符串)
  • lineno:发生错误的行号(数字)
  • colno:发生错误的列号(数字)
  • error:Error对象(对象)

unhandledrejection

The unhandledrejection event is sent to the global scope of a script when a JavaScript Promise that has no rejection handler is rejected; typically, this is the window, but may also be a Worker. This is useful for debugging and for providing fallback error handling for unexpected situations.

用来捕获 Promise 未处理 reject ,但是返回的信息只有 promise 和 reason ,没有其他具体信息

window.addEventListener("unhandledrejection", event => {
  console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}`);
}, true);

image.png

今天的文章JS错误捕获分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/18463.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注