如何追踪线上错误

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 如何追踪线上错误

前情提要

这个问题从我接手的第一个项目开始就遇到过这个问题,那时候还是在游戏组实习,就听隔壁前端组的大喊大叫,为什么有用户反应又出了什么什么问题,怎么又又用不了了。

程序员小哥很淡定的说:“用户用什么浏览器?怎么重现?”。


这个问题对于程序员来说是比较常见的,可能潜意识里面很难理解,竟然有用户不知道自己用的是什么浏览器。然后客服就去沟通用户。

用户反馈:“啊,不就是手机自带的浏览器!”

程序员:“他用什么手机?什么版本,安卓还是ios,安卓版本多少?发生错误之前都做了什么操作?”

客服:“?” 用户:“?”


有趣的是,这个问题来来回回沟通了两三天时间,最后因为用户用的手机是安卓版本较低的,我们公司找不到重现的机子,最终最开始大喊大叫的经理说,“等找到重现手机再说吧,反正也只有这一个用户遇到这个问题”。


后来如何,我想大家都很清楚了。只要是“等以后在做,后续优化”,那基本上这个需求就是被毙了。


那时候我就在想,是只有那一个手机遇到问题,还是那一系列手机都有问题?只有这一个用户遇到这个问题,是真的只有他遇到问题,还是只有他反馈问题呢?其实做开发的,收到正反馈的机会,会比收到负反馈的机会要少的多。有没有什么方式,能够自动记录下来所有用户遇到的问题呢?然后把程序员需要的数据正确反馈上来?


回到我们的问题上,如何追踪线上的错误?那你知不知道如何追踪本地错误呢?(在不打开控制台,没有 debug 的时候。)



如何捕获程序错误?

如何捕获js原生错误?

这个算是基本的js的操作了,其实就是监听 window.onerror。

<!DOCTYPE html>
<html lang="en">
<head>
  <script>
    window.onerror = function (message, source, lineno, colno, exception) {
      console.log(message);
      console.log(source);
      console.log(lineno);
      console.log(colno);
      console.log(exception);
    }
  </script>
  <script>
    var a -1;
  </script>
</head>
<body>
</body>
</html>


打开控制台你将看到这样的打印信息。

Uncaught SyntaxError: Unexpected token '-' 
file:///Users/xiaohuoni/blog/blog/index.html
15
11
SyntaxError: Unexpected token '-'


出了常见的语法错误,js 中还提供了一个事件 - onunhandledrejection - 当Promise 被 reject 且没有 reject 处理器的时候,会触发 unhandledrejection 事件;

<!DOCTYPE html>
<html lang="en">
<head>
  <script>
    window.onerror = function (message, source, lineno, colno, exception) {
      console.log(message);
      console.log(source);
      console.log(lineno);
      console.log(colno);
      console.log(exception);
    }
    window.onunhandledrejection = event => {
      console.warn(`UNHANDLED PROMISE REJECTION: ${JSON.stringify(event.reason)}`);
      event.preventDefault();
    };
  </script>
  <script>
    function myExecutorFunc(resolutionFunc, rejectionFunc) {
      rejectionFunc(777);
    }
    var myPromise = new Promise(myExecutorFunc);
  </script>
</head>
<body>
</body>
</html>

要消除上述的错误,仅仅需要 var myPromise = new Promise(myExecutorFunc).then().catch((data) => console.log(data))

上面的方法就可以帮我们正确的捕获到原生的 js 错误了。我们只需要把收到的数据,通过接口调用发送到远程服务器就可以在后台查看数据了。


如何捕获 react 中的错误

部分 UI 的 JavaScript 错误不应该导致整个应用崩溃,为了解决这个问题,React 16 引入了一个新的概念 —— 错误边界。

以下引用下官网的例子就能明白了。

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
  static getDerivedStateFromError(error) {
    // 更新 state 使下一次渲染能够显示降级后的 UI
    return { hasError: true };
  }
  componentDidCatch(error, errorInfo) {
    // 你同样可以将错误日志上报给服务器
    logErrorToMyService(error, errorInfo);
  }
  render() {
    if (this.state.hasError) {
      // 你可以自定义降级后的 UI 并渲染
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children; 
  }
}

我们可以在这里将错误日志上报给服务器。这样我们就完成了错误日志收集服务的前端开发了。希望对想自己搭建错误日志平台的朋友有所帮助。



如何捕获线上的错误

当然如果你没有自己的服务器,或者只是一个小项目,不想耗费这么大的经历去实现这个平台,现在社区上也有很多开源的平台可以选择,这里推荐一个 sentry。他的后台是免费的,提供非常多的跨平台接入方式,包括 js、React、React Native 和原生应用等97个不同的平台。


如果是 umi 项目的话,可以直接使用插件 @alitajs/sentry

安装之后增加配置

import { defineConfig } from 'umi';
export default defineConfig({
  plugins: ['@alitajs/sentry'],
  sentry: {
    dsn: '可以访问 https://sentry.io/ 免费申请,记得选 react 项目类型',
  },
});


这样你就可以在后台看到项目运行时的错误日志和发生错误的堆栈了。并且再发生错误的时候,还可以重制状态,比如在某个异常情况下服务器 504 了,你本地刚好挂了,这时候用户只要点一下,'reset' 按钮就可以恢复项目当前运行状态。还可以通过配置,在发生错误时,向用户展示用户反馈的表单。


最后简单的演示一下,sentry 的后台。(在 umi 项目或者 alita 项目中,只需要简单配置就可以实现。)



sentry 后台展示

image.png

image.png

感谢阅读,有任何疑问可以通过评论一起讨论。喜欢这个文章的朋友,请给一个赞,喜欢我的朋友,可以关注一下我。感谢三连。

相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
目录
相关文章
|
前端开发 JavaScript API
020 Umi@4 中如何实现动态菜单
020 Umi@4 中如何实现动态菜单
1253 0
020 Umi@4 中如何实现动态菜单
|
9月前
|
人工智能 自然语言处理 BI
蓝凌aiKM,双能驱动场景变革:蓝凌知识管理平台和通义千问共建实践
蓝凌aiKM通过双能驱动场景变革,结合蓝凌知识管理平台与通义千问大模型,助力企业构建智能“大脑”。aiKM不仅提升知识管理效率,还赋能业务场景,如新人培训、营销支持和流程优化。蓝博士产品整合专属内容与大模型能力,提供智能搜索、问答及推荐服务,帮助企业高效利用私域知识资产,推动数字化转型。蓝凌在AI时代致力于激活企业新生产力,打造知识护城河,成为核心竞争力。
324 0
|
9月前
|
监控 前端开发 关系型数据库
搭建直播网站技术层面准备全流程
搭建直播网站涉及技术选型、开发与部署。技术选型包括服务器端(Java/Go、MySQL/PostgreSQL、Redis、阿里云OSS等)、前端(React/Vue.js、React Native/Flutter)、流媒体技术(RTMP、HLS、WebRTC、H.264/AAC)和CDN加速。系统架构设计涵盖前端、后端、流媒体服务器及数据库,使用负载均衡器分发流量,包含用户认证、推拉流管理、实时通信等功能模块。开发流程包括环境搭建、API实现、WebSocket通信、页面开发及流媒体配置。部署阶段涉及服务器搭建、Docker容器化、CDN配置、日志监控及CI/CD自动化部署。
1141 13
|
监控 安全 网络安全
非军事区 (DMZ) 在网络安全中的概念
【8月更文挑战第27天】
1477 0
|
存储 SQL 分布式计算
MaxCompute产品使用问题之如何查看项目空间耗用的存储大小
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
233 3
|
关系型数据库 MySQL Java
如何快速搭建自己的阿里云服务器(宝塔、Xshell、Xftp配置)(二)
如何快速搭建自己的阿里云服务器(宝塔、Xshell、Xftp配置)
484 0
|
Android开发 计算机视觉 iOS开发
Flutter图片压缩库对比
Flutter图片压缩库对比 在Flutter应用程序开发中,图片压缩是一个非常重要的话题。在本文中,我们将比较一些常用的Flutter图片压缩库,以便您可以选择适合您应用程序的最佳选项。
513 0
|
存储 程序员 数据库
数据库系统结构、数据库系统的组成
数据库系统结构、数据库系统的组成
485 0
|
Kubernetes 关系型数据库 微服务
解决微服务架构下流量有损问题的实践和探索
绝⼤多数的软件应⽤⽣产安全事故发⽣在应⽤上下线发布阶段,尽管通过遵守业界约定俗成的可灰度、可观测和可滚回的安全⽣产三板斧,可以最⼤限度的规避发布过程中由于应⽤⾃身代码问题对⽤户造成的影响。但对于⾼并发⼤流量情况下的短时间流量有损问题却仍然⽆法解决。因此,本文将围绕发布过程中如何解决流量有损问题实现应⽤发布过程中的⽆损上下线效果相关内容展开⽅案介绍。
解决微服务架构下流量有损问题的实践和探索
|
缓存 移动开发
网友需求 - 使用 50 行代码在 Ant Design Pro 中完成 Umi 状态保持的多tabs布局
网友需求 - 使用 50 行代码在 Ant Design Pro 中完成 Umi 状态保持的多tabs布局
2270 1
网友需求 - 使用 50 行代码在 Ant Design Pro 中完成 Umi 状态保持的多tabs布局