赞
踩
在使用部分小程序 API / 组件时,抛出的异常(fail 回调 / Promise reject)Error
对象中除了带有 errMsg
,还会带有通用错误码 errno
。
代码示例
- wx.openBluetoothAdapter({
- success (res) {
- console.log(res)
- }
- fail (err) {
- console.log(err.errno)
- }
- })
errno
错误码的出现是为了解决以下问题:
errMsg
,没有错误码。另一部分 API 虽然有 errCode,但没有形成统一格式规范。因此,我们设计了一套拥有统一规范的错误码errno
,以帮助开发者更好地开发调试及处理错误。
errno
错误码有如下优点:
当 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
- mDNS07
- 支付
00
- 通用支付错误01
- 支付默认二级类目11
- 媒体
07
- 实时音视频13
- 文件
00
- 通用文件错误01
- 文件默认二级类目02
- fd接口14
- 开放接口
16
- 视频号15
- 设备
00
- 通用设备错误04
- NFC05
- Wi-Fi09
- 低功耗蓝牙10
- 蓝牙20
- AI
02
- 人脸识别03
- vision kit04
- 机器学习一级类目与二级类目名称 和 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: '微信无法使用蓝牙,请到系统设置中启用'
- })
- }
- }
- })
在真机上,如果想要查看 console
API 输出的日志内容和额外的调试信息,需要在点击屏幕右上角的按钮打开的菜单里选择「打开调试」。此时小程序/小游戏会退出,重新打开后右下角会出现一个 vConsole
按钮。点击 vConsole
按钮可以打开日志面板。
小程序和小游戏的 vConsole 展示内容会有一定差别,下图左边是小程序 vConsole,右边是小游戏 vConsole
由于实现机制的限制,开发者调用 console
API 打印的日志内容,是转换成 JSON
字符串后传输给 vConsole
的,导致 vConsole
中展示的内容会有一些限制:
Number
、String
、Boolean
、null
外,其他类型都会被作为 Object
处理展示,打印对象及原型链中的 Enumerable 属性。Infinity
和 NaN
会显示为 null
。undefined
、ArrayBuffer
、Function
类型无法显示- let a = {}
- a.b = a
- console.log(a) // 2.3.2 以下版本,会打印 `An object width circular reference can't be logged`
针对上述问题,小程序/小游戏在使用 vConsole 时做了一些处理
@
表示对象本身。- 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>
,此时需要开发者裁剪日志内容。
目前只在 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 文件进行错误分析
.map
文件,实际代码包大小会比体验版和正式版大。为帮助小程序开发者快捷地排查小程序漏洞、定位问题,我们推出了实时日志功能。开发者可通过提供的接口打印日志,日志汇聚并实时上报到小程序后台。开发者可从We分析“性能质量->实时日志->小程序日志”进入小程序端日志查询页面,或从“性能质量->实时日志->插件日志”进入插件端日志查询页面,进而查看开发者打印的日志信息。
从基础库2.7.1
开始,小程序端即可使用实时日志,小游戏端则从基础库2.14.4
开始支持。
1、调用相关接口。打日志的接口是wx.getRealtimeLogManager
,为了兼容旧的版本,建议使用如下代码封装一下,例如封装在log.js
文件里面:
- var log = wx.getRealtimeLogManager ? wx.getRealtimeLogManager() : null
-
- module.exports = {
- debug() {
- if (!log) return
- log.debug.apply(log, arguments)
- },
- info() {
- if (!log) return
- log.info.apply(log, arguments)
- },
- warn() {
- if (!log) return
- log.warn.apply(log, arguments)
- },
- error() {
- if (!log) return
- log.error.apply(log, arguments)
- },
- setFilterMsg(msg) { // 从基础库2.7.3开始支持
- if (!log || !log.setFilterMsg) return
- if (typeof msg !== 'string') return
- log.setFilterMsg(msg)
- },
- addFilterMsg(msg) { // 从基础库2.8.1开始支持
- if (!log || !log.addFilterMsg) return
- if (typeof msg !== 'string') return
- log.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)等筛选条件查询指定用户的日志信息。如果是插件上报的实时日志,可从“小程序插件->实时日志”进入日志查询页面进行查询。
由于后台资源限制,“实时日志”使用规则如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。