当前位置: 首页 > news >正文

如何进行小程序的调试

Errno错误码

在使用部分小程序 API / 组件时,抛出的异常(fail 回调 / Promise reject)Error 对象中除了带有 errMsg,还会带有通用错误码 errno

代码示例

wx.openBluetoothAdapter({success (res) {console.log(res)}fail (err) {console.log(err.errno)}
})

背景介绍

errno 错误码的出现是为了解决以下问题:

  • 目前部分 API 在出现错误时,只返回错误信息 errMsg,没有错误码。另一部分 API 虽然有 errCode,但没有形成统一格式规范。
  • 目前有 errCode 的 API 中,不同的 API 失败时返回的 errCode 粒度不同。部分 API 的 errCode 粒度太大,信息不足。
  • 相同的错误在不同的 API 中 errCode 未对齐,不便于开发者记忆和处理。

因此,我们设计了一套拥有统一规范的错误码errno,以帮助开发者更好地开发调试及处理错误。

errno 错误码有如下优点:

  • 在错误码格式上,拥有统一的设计规范。
  • 不同的 API 中出现的相同错误,对应的错误码一致。
  • 错误码中包含 API 类别信息,帮助开发者快速定位问题。
  • 不同 API 中的错误码粒度较为统一。

当 Error 对象中同时有 errno 错误码和 errCode 错误码时,一般以 errno 错误码为准
后续 errno 错误码会逐步推广到所有 API 接口,并取代现有的 errCode 参数,为开发者提供错误信息。

错误码设计

errno 错误码一般为 7 位数,第 1 - 2 位标识 API 接口的一级类目,第 3 - 4 位标识 API 接口的二级类目,第 5 - 7 位表示具体的错误类型。
例如: errno 错误码为 1504003 时,15 表示 API 接口的一级类目为 设备,04 表示 API 接口的二级类目为 NFC,003 表示具体的错误类型。
目前已接入 errno 的 API 接口涉及的类目包括:

  • 一级类目:00 - 通用错误码
  • 一级类目:01 - 基础
    • 二级类目:00 - 通用基础错误
    • 二级类目:03 - 更新
    • 二级类目:09 - 加密
  • 一级类目:06 - 网络
    • 二级类目:00 - 通用网络错误
    • 二级类目:02 - 发起请求
    • 二级类目:03 - 下载
    • 二级类目:04 - 上传
    • 二级类目:06 - mDNS
  • 一级类目:07 - 支付
    • 二级类目:00 - 通用支付错误
    • 二级类目:01 - 支付默认二级类目
  • 一级类目:11 - 媒体
    • 二级类目:07 - 实时音视频
  • 一级类目:13 - 文件
    • 二级类目:00 - 通用文件错误
    • 二级类目:01 - 文件默认二级类目
    • 二级类目:02 - fd接口
  • 一级类目:14 - 开放接口
    • 二级类目:16 - 视频号
  • 一级类目:15 - 设备
    • 二级类目:00 - 通用设备错误
    • 二级类目:04 - NFC
    • 二级类目:05 - Wi-Fi
    • 二级类目:09 - 低功耗蓝牙
    • 二级类目:10 - 蓝牙
  • 一级类目:20 - AI
    • 二级类目:02 - 人脸识别
    • 二级类目:03 - vision kit
    • 二级类目:04 - 机器学习

一级类目与二级类目名称 和 API 接口文档的类目名称基本保持一致。

最佳实践

以 API 接口 openBluetoothAdapter 为例,当蓝牙适配器不可用时,针对 openBluetoothAdapter 接口抛出的异常 Error 对象:

"err":
{"errMsg": "openBluetoothAdapter:fail:not available","errCode": 10001,"errno": 1500102
}

可以通过以下代码进行异常处理:

wx.openBluetoothAdapter({success (res) {console.log(res)},fail (err) {// 微信无法使用蓝牙,可引导用户在系统设置中启用蓝牙if ( err.errno === 1500102 ) {wx.showModal({content: '微信无法使用蓝牙,请到系统设置中启用'})}}
})

错误码

vConsole

在真机上,如果想要查看 console API 输出的日志内容和额外的调试信息,需要在点击屏幕右上角的按钮打开的菜单里选择「打开调试」。此时小程序/小游戏会退出,重新打开后右下角会出现一个 vConsole 按钮。点击 vConsole 按钮可以打开日志面板。

小程序和小游戏的 vConsole 展示内容会有一定差别,下图左边是小程序 vConsole,右边是小游戏 vConsole

 

vConsole 使用说明

由于实现机制的限制,开发者调用 console API 打印的日志内容,是转换成 JSON 字符串后传输给 vConsole 的,导致 vConsole 中展示的内容会有一些限制:

  • 除了 NumberStringBooleannull 外,其他类型都会被作为 Object 处理展示,打印对象及原型链中的 Enumerable 属性。
  • Infinity 和 NaN 会显示为 null
  • undefinedArrayBufferFunction 类型无法显示
  • 无法打印存在循环引用的对象
let a = {}
a.b = a
console.log(a) // 2.3.2 以下版本,会打印 `An object width circular reference can't be logged`

针对上述问题,小程序/小游戏在使用 vConsole 时做了一些处理

  • 2.3.2 及以上版本,支持打印循环引用对象。循环引用的对象属性会显示引用路径,@表示对象本身。
const circular = { x: {}, c: {} }
circular.x = [{ promise: Promise.resolve() }]
circular.a = circular
circular.c.x0 = circular.x[0]console.log(circular)
// "{a: '<Circular: @>', c: {x0: '<Circular: @.x[0]>'}, x: [{promise: '<Promise>'}]}"
  • 2.3.1 及以上版本,支持展示所有类型的数据。基础库会对日志内容进行一次转换,经过转换的内容会使用<>包裹。如:

    • <Function: func>
    • <Undefined>
    • <Infinity>
    • <Map: size=0>
    • <ArrayBuffer: byteLength=10>
    • ...
  • 2.2.3 ~ 2.3.0 版本中,可以展示 ArrayBuffer 和 Function 类型,undefined 会被打印为字符串 'undefined'

注:尽量避免在非调试情景下打印结构过于复杂或内容过长的日志内容(如游戏引擎中的精灵或材质对象等),可能会带来额外耗时。为了防止异常发生,日志内容超过一定长度会被替换为<LOG_EXCEED_MAX_LENGTH>,此时需要开发者裁剪日志内容。

Source Map

目前只在 iOS 6.7.2 及以上版本支持

小程序/小游戏在打包时,会将所有 JavaScript 代码打包成一个文件,为了便于开发者在手机上调试时定位错误位置,小程序/小游戏提供了 Source Map 支持。

在开发者工具中开启 ES6 转 ES5、代码压缩时,会生成 Source Map 的 .map 文件。开发版小程序中,基础库会使用代码包中的 .map 文件,对 vConsole 中展示的错误信息堆栈进行重新映射(只对开发者代码文件进行)。

如果使用外部的编译脚本对源文件进行处理,只需将对应生成的 Source Map 文件放置在源文件的相同目录下

如:

pages/index.js
pages/index.js.map
app.js
app.js.map

开发者工具会读取、解析 Source Map 文件,并进行将其上传

后续可以在小程序后台的运营中心可以利用上传的 Source Map 文件进行错误分析

注意事项

  1. Source Map 文件不计入代码包大小计算,也不会被包含在体验版/正式版代码包中。
  2. inline sourcemap 不计入代码包大小计算。
  3. 开发版代码包中由于包含了 .map 文件,实际代码包大小会比体验版和正式版大。

实时日志

背景

为帮助小程序开发者快捷地排查小程序漏洞、定位问题,我们推出了实时日志功能。开发者可通过提供的接口打印日志,日志汇聚并实时上报到小程序后台。开发者可从We分析“性能质量->实时日志->小程序日志”进入小程序端日志查询页面,或从“性能质量->实时日志->插件日志”进入插件端日志查询页面,进而查看开发者打印的日志信息。

如何使用

小程序/小游戏端

从基础库2.7.1开始,小程序端即可使用实时日志,小游戏端则从基础库2.14.4开始支持。

1、调用相关接口。打日志的接口是wx.getRealtimeLogManager,为了兼容旧的版本,建议使用如下代码封装一下,例如封装在log.js文件里面:

var log = wx.getRealtimeLogManager ? wx.getRealtimeLogManager() : nullmodule.exports = {debug() {if (!log) returnlog.debug.apply(log, arguments)},info() {if (!log) returnlog.info.apply(log, arguments)},warn() {if (!log) returnlog.warn.apply(log, arguments)},error() {if (!log) returnlog.error.apply(log, arguments)},setFilterMsg(msg) { // 从基础库2.7.3开始支持if (!log || !log.setFilterMsg) returnif (typeof msg !== 'string') returnlog.setFilterMsg(msg)},addFilterMsg(msg) { // 从基础库2.8.1开始支持if (!log || !log.addFilterMsg) returnif (typeof msg !== 'string') returnlog.addFilterMsg(msg)}
}

2、在页面的具体位置打印日志:

var log = require('./log.js') // 引用上面的log.js文件
log.info('hello test hahaha') // 日志会和当前打开的页面关联,建议在页面的onHide、onShow等生命周期里面打
log.warn('warn')
log.error('error')
log.setFilterMsg('filterkeyword')
log.addFilterMsg('addfilterkeyword')

完整的例子可以参考代码片段:https://developers.weixin.qq.com/s/aFYw1BmC7eak

插件端

从基础库2.16.0开始支持,插件端也支持了实时日志。为了让日志更具有结构性,以便后续进行更为复杂的分析,因此插件端采用新设计的格式。

1、调用相关接口 wx.getRealtimeLogManager,获取实时日志管理器实例:

const logManager = wx.getRealtimeLogManager()

2、在需要打日志的逻辑中,获取日志实例:

// 标签名可以是任意字符串,一个标签名对应一组日志;同样的标签名允许被重复使用,具有相同标签名的日志在后台会被汇总到一个标签下
// 标签可为日志进行分类,因此建议开发者按逻辑来进行标签划分
const logger = logManager.tag('plugin-onUserTapSth')

3、在合适位置打印日志:

logger.info('key1', 'value1') // 每条日志为一个 key-value 对,key 必须是字符串,value 可以是字符串/数值/对象/数组等可序列化类型
logger.error('key2', {str: 'value2'})
logger.warn('key3', 'value3')
logger.setFilterMsg('filterkeyword') // 和小程序/小游戏端接口一致
logger.setFilterMsg('addfilterkeyword') // 和小程序/小游戏端接口一致

如何查看日志

登录We分析,从“性能质量->实时日志”进入日志查询页面。开发者可通过设置时间、微信号/OpenID、页面链接、FilterMsg内容(基础库2.7.3及以上支持setFilterMsg)等筛选条件查询指定用户的日志信息。如果是插件上报的实时日志,可从“小程序插件->实时日志”进入日志查询页面进行查询。

./log2.png

注意事项

由于后台资源限制,“实时日志”使用规则如下:

  1. 为了定位问题方便,日志是按页面划分的,某一个页面,在一定时间内(最短为5秒,最长为页面从显示到隐藏的时间间隔)打的日志,会聚合成一条日志上报,并且在小程序管理后台上可以根据页面路径搜索出该条日志
  2. 每个小程序账号,We分析基础版每天限制5000条日志,We分析专业版为50000条,且支持购买配置升级或购买额外的上报扩充包。日志根据版本配置,会保留7天/14天/30天不等,建议遇到问题及时定位。
  3. 一条日志的上限是5KB,最多包含200次打印日志函数调用(info、warn、error调用都算),所以要谨慎打日志,避免在循环里面调用打日志接口,避免直接重写console.log的方式打日志。
  4. 意见反馈里面的日志,可根据OpenID搜索日志。
  5. setFilterMsg和addFilterMsg 可设置类似日志tag的过滤字段。如需添加多个关键字,建议使用addFilterMsg。例如addFilterMsg('scene1'), addFilterMsg('scene2'),addFilterMsg('scene3'),设置后在小程序管理后台可随机组合三个关键字进行检索,如:“scene1 scene2 scene3”、“scene1 scene2”、 “scene1 scene3” 或 “scene2”等(以空格分隔,故addFilterMsg不能带空格)。以上几种检索方法均可检索到该条日志,检索条件越多越精准。
  6. 目前为了方便做日志分析,插件端实时日志只支持 key-value 格式。
  7. 实时日志目前只支持在手机端测试。工具端的接口可以调用,但不会上报到后台。
  8. 开发版、体验版的实时日志,不计入相关quota,即无使用上限。

filtermsg

相关文章:

  • c++基础2
  • 在WPF中使用WebView2详解
  • Angular 18.2.0 的新功能增强和创新
  • 问题记录-SpringBoot 2.7.2 整合 Swagger 报错
  • html必知必会-html内嵌JavaScript和文件路径
  • 如何使用大语言模型绘制专业图表
  • Sqlmap中文使用手册 - Techniques模块参数使用
  • 最新源支付系统源码 V7版全开源 免授权 附搭建教程
  • C++ | Leetcode C++题解之第278题第一个错误的版本
  • Vue2和Vue3实战代码中的小差异(实时更新)
  • ELK安装(Elasticsearch+Logstash+Kibana+Filebeat)
  • PHP家政系统自营+多商户独立端口系统源码小程序
  • Vue中el的两种写法
  • 深入MySQL中的IF和IFNULL函数
  • 汉明权重(Hamming Weight)(统计数据中1的个数)VP-SWAR算法
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • 【刷算法】从上往下打印二叉树
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • AHK 中 = 和 == 等比较运算符的用法
  • JavaScript 奇技淫巧
  • java多线程
  • PHP 小技巧
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • vue自定义指令实现v-tap插件
  • 阿里云应用高可用服务公测发布
  • 关键词挖掘技术哪家强(一)基于node.js技术开发一个关键字查询工具
  • 技术胖1-4季视频复习— (看视频笔记)
  • 你不可错过的前端面试题(一)
  • 前端技术周刊 2019-01-14:客户端存储
  • 前端路由实现-history
  • 一道面试题引发的“血案”
  • 一起来学SpringBoot | 第三篇:SpringBoot日志配置
  • ​​​【收录 Hello 算法】9.4 小结
  • #java学习笔记(面向对象)----(未完结)
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • (1)Jupyter Notebook 下载及安装
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (排序详解之 堆排序)
  • (三)SvelteKit教程:layout 文件
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • .htaccess配置常用技巧
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .Net IOC框架入门之一 Unity
  • .NET 使用 XPath 来读写 XML 文件
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)
  • .NET/C# 将一个命令行参数字符串转换为命令行参数数组 args
  • .NET实现之(自动更新)
  • .NET中winform传递参数至Url并获得返回值或文件
  • @vue/cli脚手架
  • [ 网络通信基础 ]——网络的传输介质(双绞线,光纤,标准,线序)
  • [].slice.call()将类数组转化为真正的数组
  • []error LNK2001: unresolved external symbol _m