为什么要用云开发做错误日志:
我司没有测试,所以产品上线的话比较多不确定性
云开发业务并不稳定,且有限制,所以不建议直接用做整个小程序的后台开发。
做错误日志并不会影响小程序的流程
出bug后,难定位问题,尤其是线上错误
如果叫后端小伙伴给接口记录错误,总是不方便,还是自己动手丰衣足食
尝鲜
基于以上的原因,在小程序云开发刚出来没多久,我就开始着手在我的小程序上尝试构建一个错误日志:
一般用一门新技术的第一步,你需要先浏览一下小程序云开发的官方文档:
https://developers.weixin.qq....
初始化环境
然后你需要一个小程序,一个小程序开发工具:
新建一个空白的小程序后,点击左上角的云开发按钮,初始化一个云开发的环境
我这里给它取名叫error-storage。当然我是因为之后我的小程序也不太可能会用到云开发做后台,所以可以浪费一个环境命名。如果你是要用云开发做后台业务的话。那么还是按照微信推荐,一个做测试一个做正式,命名也尽量规范一点。
然后它的环境限制也是我们目前不拿它当主要后端脚本的主要原因之一。
ok,点击确定就创建了一个云开发后台了。
然后我们回到代码。
我们需要写后端脚本记录错误信息,那么根据云开发的文档,我们需要修改project.config.json
给他配置一下小程序代码放在哪里,后端代码放在哪里。
以下是我的配置:
我把小程序文件都放在了根目录下的client文件夹内,而云函数的文件则都放在了根目录的server文件夹的cloudFunctions里
那么现在我们的目录结构是这样的。我们需要手动移动一下我们的小程序代码。
注意这里project.config.json是在根目录
现在先添加一个数据库集合,打开云开发控制台,点击数据库。添加一个叫errors的集合
编写接收错误的云函数
然后我们先开始写接收错误的云函数
用微信开发工具打开代码,然后点击目录树上面的cloudFunctiions目录,新建一个云函数,我们将它取名叫做errorHandler
然后写上我们的代码逻辑
// 云函数入口文件
const cloud = require('wx-server-sdk');
cloud.init();
const db = cloud.database();
const errorCllection = db.collection('errors');
function addError(data) {
return errorCllection.add({
data: {
...data,
createTime: Date.now()
}
});
}
// 云函数入口函数
exports.main = async event => {
event.openid = event.userInfo.openId;
delete event.userInfo;
await addError(event);
return true;
};
这面这段代码很简单就是将小程序端传过来的错误写进数据库里面,错误信息是什么由小程序端决定,它仅仅只是将所有数据丢进数据库去而已
保存字后再次右键cloudFunctions选择上传并部署。那么我们的服务端就基本搞定了。(好简单啊)
写小程序端的错误处理函数
首先,根据教程,我们要在app.js里面做云能力初始化
在app.js的第一行添加代码
try {
wx.cloud.init({ // 云开发初始化
env: '云环境id',
traceUser: true
});
} catch(err) {}
给它加上catch是因为防止出现一些错误导致app.js运行失败,那简直是灾难吧!
这里的env是你的云环境id,那么在哪里拿呢,在这里
然后我们在client/utils文件夹里面添加一个处理错误的模块吧
名字就叫 error.js
const { config } = require('./config.js');
global.onError = function (message, showModal = true) {
return function (error) {
wx.hideLoading();
if (showModal) {
wx.showModal({
title: '错误',
content: error.msg || message,
// 这里的error.msg是因为与后端约定如果有什么错误,则带一个msg的描述
// 而message则是传入进来备用的错误信息
confirmText: '返回首页',
cancelText: '继续操作',
success: res => {
if (res.confirm) {
// 重新加载首页
wx.switchTab({
url: '/pages/index/index'
});
} else {
// 取消就不管了
}
}
});
}
// 上传到小程序云数据库
try {
let userInfo = getApp().globalData.userInfo,
systemInfo = wx.getSystemInfoSync(),
page = getCurrentPages();
// 只有不在开发工具上触发的才上报
if (systemInfo.platform !== 'devtools') {
wx.getNetworkType({
success: res => {
wx.cloud.callFunction({
name: 'errorHandler',
data: {
username: userInfo.nickName,
uid: userInfo.id,
clientType: systemInfo.model,
systemInfo: JSON.stringify(systemInfo),
pageRoute: page[page.length - 1].route,
message: error.msg || message,
version: config.version,
networkType: res.networkType,
errorTime: new Date(),
error: typeof error === 'object' ? JSON.stringify(error) : String(error)
}
});
}
});
}
} catch(err) {}
console.error('程序发生错误:\n', '时间:\n', new Date(), '\n错误信息:\n', message, '\nvvvvvvvvvvvvvv\n', error);
};
};