前端错误收集与处理

这篇具有很好参考价值的文章主要介绍了前端错误收集与处理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

做好错误监控,将用户使用时的错误日志上报,可以帮助我们更快的解决一些问题。

那前端监控是怎么实现的呢?要想了解这个,需要知道前端错误大概分为哪些以及如何捕获处理。

前端错误分为JS运行时错误、资源加载错误和接口错误三种。

本文档介绍有关js的错误类型、错误事件、vue3的app.config.errorHandler全局处理函数。

用nodejs+Express模拟接口,将监听到的错误信息发送到nodejs写的接口里,再通过一个getErrorList接口展示错误信息列表。

js的错误对象和onerror事件

2.1错误对象类型

ECMA-262定义了下列7种错误类型:https://baike.baidu.com/item/ECMAScript/1889420?fr=aladdin

Error() // 基类型

EvalError() // eval错误

RangeError() // 范围错误

ReferenceError() // 引用错误

SyntaxError() // 语法错误

TypeError() // 类型错误

URIError() // URI错误

Error: 所有错误类型的父类型。

SyntaxError: 语法错误,表示程序的语法使用错误。

console.log(【】) ; VM115:1 Uncaught SyntaxError: Invalid or unexpected token

ReferenceError: 引用错误,表示引用的变量不存在。

console.log(a) ; VM274:1 Uncaught ReferenceError: a is not defined at <anonymous>:1:13

TypeError: 类型错误,表示使用了错误的数据类型。

let a;
console.log(a.name); 
VM279:2 Uncaught TypeError: Cannot read properties of undefined (reading 'name')
    at <anonymous>:2:15

RangeError:范围错误, 数据值不在其所允许的范围内(函数递归调用容易出现此错误)。

(10.24).toFixed(-1)
VM363:2 Uncaught RangeError: toFixed() digits argument must be between 0 and 100
    at Number.toFixed (<anonymous>)
    at <anonymous>:2:9

URIError: URI错误,向全局 URI 处理函数(decodeURI、decodeURIComponent)传递一个不合法的URI时,URIError 错误会被抛出。

// 解码URI地址   错误:格式不正确
console.log(decodeURI("%") );
VM368:2 Uncaught URIError: URI malformed
    at decodeURI (<anonymous>)
    at <anonymous>:2:13

EvelError: eval函数执行错误 EvalError 不在当前ECMAScript规范中使用,因此不会被运行时抛出。但是对象本身仍然与规范的早期版本向后兼容。

通过error的构造器可以创建一个错误对象。如 new error() throw new Error(); 这个是创建错误,创造一个错误类型抛出。

app.config.errorhandler,前端,javascript,开发语言

 

// 抛出的地方
function parseExcel(con) {
   try {
        // doSomething
    } catch (error) {
        throw new Error('parse excel failed');
    }
}
// 捕获的地方 
try {
    parseExcel(con);
} catch (error) {
    if (error.message === 'parse excel failed') {
        //doSomething
    }
}

2.2Error对象

--error 对象是当错误发生时提供错误信息的 JS 内置对象。

当错误发生时,浏览器会生成 error 对象并抛出,并且中断后面代码的执行。

console.log(js)
console.log('中断后面代码的执行,不会被执行到')
VM488:1 Uncaught ReferenceError: js is not defined
    at <anonymous>:1:13

任何没有通过try-catch处理的错误都会触发window对象的error事件。

error事件接收五个参数:

message:错误信息(字符串)

source:发生错误的脚本URL(字符串)

lineno:发生错误的行号(数字)

colno:发生错误的列号(数字)

error:Error对象(对象)

app.config.errorhandler,前端,javascript,开发语言

 app.config.errorhandler,前端,javascript,开发语言

 

图像也支持error事件。

var img = new Image()
img.src='a.jpg'
img.onerror = function(e) {
  console.log(e)
}

2.3资源加载失败

window.addEventListener 当一项资源(如图片或脚本)加载失败,加载资源的元素会触发一个 Event 接口的 error 事件,这些 error 事件不会向上冒泡到 window,但能被捕获。而window.onerror不能监测捕获。

// 图片、script、css加载错误,都能被捕获 ✅
<script>
  window.addEventListener('error', (error) => {
     console.log('捕获到异常:', error);
  }, true)
</script>
<img src="https://yun.tuia.cn/image/kkk.png">
<script src="https://yun.tuia.cn/foundnull.js"></script>
<link href="https://yun.tuia.cn/foundnull.css" rel="stylesheet"/>
  
// new Image错误,不能捕获 ❌
<script>
  window.addEventListener('error', (error) => {
    console.log('捕获到异常:', error);
  }, true)
</script>
<script>
  new Image().src = 'https://yun.tuia.cn/image/lll.png'
</script>

// fetch错误,不能捕获 ❌
<script>
  window.addEventListener('error', (error) => {
    console.log('捕获到异常:', error);
  }, true)
</script>
<script>
  fetch('https://tuia.cn/test')
</script>

到目前为止,还有语法错误、promise异步错误、new Image资源加载错误还没有捕获方法。

语法错误可以在开发阶段依靠编辑器发现。

new Image运用的比较少,可以单独自己处理自己的错误,可以通过img.onerror = fn来单独处理。

但通用的fetch怎么办呢,fetch返回Promise,但Promise的错误不能被捕获,怎么办呢?

Promise错误

1.普通Promise错误

try/catch不能捕获Promise中的错误

// try/catch 不能处理 JSON.parse 的错误,因为它在 Promise 中
try {
  new Promise((resolve,reject) => { 
    JSON.parse('')
    resolve();
  })
} catch(err) {
  console.error('in try catch', err)
}

// 需要使用catch方法
new Promise((resolve,reject) => { 
  JSON.parse('')
  resolve();
}).catch(err => {
  console.log('in catch fn', err)
})

2.async错误

try/catch不能捕获async包裹的错误

const getJSON = async () => {
  throw new Error('inner error')
}

// 通过try/catch处理
const makeRequest = async () => {
    try {
        // 捕获不到
        JSON.parse(getJSON());
    } catch (err) {
        console.log('outer', err);
    }
};

try {
    // try/catch不到
    makeRequest()
} catch(err) {
    console.error('in try catch', err)
}

try {
    // 需要await,才能捕获到
    await makeRequest()
} catch(err) {
    console.error('in try catch', err)
}

3.import chunk错误

import其实返回的也是一个promise,因此使用如下两种方式捕获错误

// Promise catch方法
import(/* webpackChunkName: "incentive" */'./index').then(module => {
    module.default()
}).catch((err) => {
    console.error('in catch fn', err)
})

// await 方法,try catch
try {
    const module = await import(/* webpackChunkName: "incentive" */'./index');
    module.default()
} catch(err) {
    console.error('in try catch', err)
}

小结:全局捕获Promise中的错误

以上三种其实归结为Promise类型错误,可以通过unhandledrejection捕获。 为了防止有漏掉的 Promise 异常,可通过unhandledrejection用来全局监听Uncaught Promise Error。

// 全局统一处理Promise
window.addEventListener("unhandledrejection", function(e){
  console.log('捕获到异常:', e);
});
fetch('https://tuia.cn/test')

当promise被reject并且错误信息没有被处理的时候,会抛出一个unhandledrejection,并且这个错误不会被window.onerror以及window.addEventListener('error')捕获,需要用专门的window.addEventListener('unhandledrejection')捕获处理。

window.addEventListener('unhandledrejection', event => 
    { 
       console.log('unhandledrejection:' + event.reason); // 捕获后自定义处理
    });

https://developer.mozilla.org... 例子: http://sandbox.runjs.cn/show/eatrbc1w 请打开页面打开控制台查看。点击button抛出unhandledrejection错误,并且该错误仅能被window.addEventListener('unhandledrejection')捕获。

Uncaught RangeError: Maximum call stack

这是Chrome浏览器在几种情况下出现的错误,一种是调用不终止的递归函数。你可以在Chrome开发者控制台中对此进行测试。

8、js FileReader 读取文件错误处理

const reader = new FileReader()

reader.onload = ()=>{}

reader.οnerrοr= ()=>{}

9、图片onerror事件

img标签支持onerror 事件,在装载文档或图像的过程中如果发生了错误,就会触发onerror事件。可以使用一张提示错误的图片代替显示不了的图片。

10、其他资源的onerror事件---脚本、iframe等

浏览器允许我们跟踪外部资源的加载 —— 脚本,iframe,图片等。

因此,在 onload 中我们可以使用脚本中的变量,运行函数等。 ……如果加载失败怎么办?例如,这里没有这样的脚本(error 404)或者服务器宕机(不可用)。

发生在脚本加载期间的 error 会被 error 事件跟踪到。

例如,我们请求一个不存在的脚本:

let script = document.createElement('script');
script.src = "https://example.com/404.js"; // 没有这个脚本
document.head.append(script);

script.onerror = function() {
  alert("Error loading " + this.src); // Error loading https://example.com/404.js
};

请注意,在这里我们无法获取更多 HTTP error 的详细信息。我们不知道 error 是 404 还是 500 或者其他情况。只知道是加载失败了。

  • 对于 <iframe> 来说,iframe 加载完成时会触发 iframe.onload 事件,无论是成功加载还是出现 error。

1.5 特别说明sourceMap

在线上由于JS一般都是被压缩或者打包(webpack)过,打包后的文件只有一行,因此报错会出现第一行第5000列出现JS错误,给排查带来困难。sourceMap存储打包前的JS文件和打包后的JS文件之间一个映射关系,可以根据打包后的位置快速解析出对应源文件的位置。

但是出于安全性考虑,线上设置sourceMap会存在不安全的问题,因为网站使用者可以轻易的看到网站源码,此时可以设置.map文件只能通过公司内网访问降低隐患

sourceMap配置devtool: 'inline-source-map' 如果使用了uglifyjs-webpack-plugin 必须把 sourceMap设置为true https://doc.webpack-china.org...https://doc.webpack-china.org/guides/development/#%E4%BD%BF%E7%94%A8-source-map

三、vue的app.config.errorHandler全局处理函数

由于Vue会捕获所有Vue单文件组件或者Vue.extend继承的代码,所以在Vue里面出现的错误,并不会直接被window.onerror捕获,而是会抛给Vue.config.errorHandler。

app.config.errorHandler用于为应用内抛出的未捕获错误指定一个全局处理函数。https://cn.vuejs.org/api/application.html#app-config-errorhandler

  • 详细信息

  • 错误处理器接收三个参数:错误对象、触发该错误的组件实例和一个指出错误来源类型信息的字符串。

  • 它可以从下面这些来源中捕获错误:

    • 组件渲染器

    • 事件处理器

    • 生命周期钩子

    • setup() 函数

    • 侦听器

    • 自定义指令钩子

    • 过渡 (Transition) 钩子

import { createApp } from 'vue'
import App from './App.vue'

let app = createApp(App)
app.config.errorHandler = (err, vm, info) => {
    console.log(123)
    // err:
    // vm:
    // info: 是vue特定的错误信息,比如错误所在的生命周期钩子
    console.log(err, vm, info);
    fetch("http://127.0.0.1:8081/process_post", {
        method: "POST",
        headers: {
                "Content-Type": "application/json",
        },
        mode: "no-cors",
        body: JSON.stringify({
                errorMsg: err
        })
    }).then(function(res) {
        if (res.status === 200) {
                return res.json()
        } else {
                //return Promise.reject(res.json())
        }
    }).then(function(data) {
            console.log(data);
    }).catch(function(err) {
            console.log(err);
    });
}
app.mount('#app')

仅供参考,侵权必删。文章来源地址https://www.toymoban.com/news/detail-774807.html

到了这里,关于前端错误收集与处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • JavaScript 常见错误与异常处理

    1、调试和故障排除: 了解常见的JavaScript错误可以帮助你更好地调试和故障排除代码。当你遇到错误时,能够快速识别错误类型并找到解决方法,可以节省大量的时间和精力。 2、代码质量和稳定性: 通过了解常见的JavaScript错误,你可以编写更健壮和稳定的代码。你可以预先

    2024年02月03日
    浏览(11)
  • 【JavaScript】1.5 错误处理和调试

    【JavaScript】1.5 错误处理和调试

    编程过程中,错误是无法避免的。而如何处理和调试错误,是每个开发者需要掌握的重要技能。在这一节中,我们将讨论JavaScript中的错误处理和调试。 在JavaScript中,有几种常见的错误类型: ReferenceError :当试图引用不存在的变量时,会抛出此错误。 TypeError :当数据类型不

    2024年02月05日
    浏览(5)
  • JavaScript常见报错及错误处理方法

    目录 前言 一、报错类型 1. SyntaxError(语法错误) 2. ReferenceError(引用错误) 3. TypeError(类型错误) 4. 其他错误类型 二、异常处理 try catch 1. try catch定义 2. try-catch块的工作原理 3. try-catch基本语法 4. try-catch最佳实践 在日常的前端开发中,都会遇到各种错误,所以错误处理是

    2024年02月06日
    浏览(8)
  • 使用try...catch语句优雅地处理JavaScript错误

    使用try...catch语句优雅地处理JavaScript错误

    🧑‍🎓 个人主页: 《爱蹦跶的大A阿》 🔥 当前正在更新专栏: 《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​  目录 ✨ 前言 ✨ 正文 简介 语法 示例 错误对象 抛出错误 finally 语句 总结 ✨ 结语   ​         JavaScript作为一门脚本语言,代码运行时

    2024年01月22日
    浏览(12)
  • 前端面试题---跨域处理和异常、错误处理

    在前端开发中,当我们在浏览器中向不同域名或端口发起请求时,就会遇到跨域请求的限制。为了处理跨域请求,有几种常见的方法  1.JSONP(JSON with Padding) JSONP是一种利用 script 标签可以跨域加载的特性来实现跨域请求的方法。服务器端返回的数据会被包裹在一个JavaScript函

    2024年02月08日
    浏览(8)
  • 前端异常错误处理(包括但不限于react,vue)

    错误异常发生 页面js报错 请求报错 页面资源加载报错 promise异常 iframe加载异常 页面奔溃卡顿异常 处理异常的方法 1、react 自带的errorBoundaries 2、 react 自定义Hooks 3、 vue errorHandler 4、try catch 对特定的代码进行捕获 5、window.addEventListerner 6、window.onerror 7、 window.unhandledrejection 8、

    2024年02月16日
    浏览(6)
  • C# App.config和Web.config加密

    C# App.config和Web.config加密

    使用ASP.NET提供的命令工具aspnet_regiis来创建加密命令。 这个命令将加密App.config文件中的connectionStrings设置。C:MyAppFolder是应用程序的根目录。  这个命令将会加密Web.config文件中的appSettings设置。   如果需要编辑加密的配置节,可以使用aspnet_regiis提供的解密命令。 这个命令将

    2024年02月14日
    浏览(4)
  • 渗透测试 | APP信息收集

    渗透测试 | APP信息收集

    0x00 免责声明         本文仅限于学习讨论与技术知识的分享,不得违反当地国家的法律法规。对于传播、利用文章中提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,本文作者不为此承担任何责任,一旦造成后果请自行承担!            

    2024年01月17日
    浏览(6)
  • 在Winform中动态读写app.config文件

    在Winform中动态读写app.config文件

    https://blog.csdn.net/kingmax54212008/article/details/38987277?spm=1001.2101.3001.6650.7utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-7-38987277-blog-82746084.235%5Ev36%5Epc_relevant_default_base3depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-7-38987277-blog-8274

    2024年02月06日
    浏览(6)
  • JavaScript 日期和时间的格式化大汇总(收集)

    一、日期和时间的格式化 1、原生方法 1.1、使用 toLocaleString 方法 Date 对象有一个 toLocaleString 方法,该方法可以根据本地时间和地区设置格式化日期时间。例如:   toLocaleString 方法接受两个参数,第一个参数是地区设置,第二个参数是选项,用于指定日期时间格式和时区信息

    2024年02月08日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包