aspack001
aspack001
  • 发布:2025-07-21 16:54
  • 更新:2025-08-07 00:30
  • 阅读:124

调用云对象经常报:May not write null values to stream

分类:uniCloud

有一半多的概率会报这个错,其他一般概率正常。
代码:
// 云对象教程: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj
// jsdoc语法提示教程:https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/129

const GLOBAL_CONFIG_KEY = 'global-config' // Redis中存储全局配置的key

module.exports = {
_before: function () { // 通用预处理器

},  
/**  
 * 获取全局配置  
 * @returns {object} 返回全局配置  
 */  
async getGlobalConfig() {  
    try {  
        const redis = uniCloud.redis()  

        // 先从Redis获取  
        const redisConfig = await redis.get(GLOBAL_CONFIG_KEY)  
        if (redisConfig) {  
            console.log('从Redis获取到全局配置')  
            return {  
                code: 0,  
                msg: '获取成功(Redis)',  
                data: JSON.parse(redisConfig)  
            }  
        }  

        // Redis没有,从数据库获取  
        console.log('Redis中无配置,从数据库获取')  
        const db = uniCloud.database()  
        const configRecord = await db.collection('config').where({  
            key: GLOBAL_CONFIG_KEY  
        }).get()  

        const resultData = configRecord.data || (configRecord.result && configRecord.result.data) || []  

        if (resultData.length > 0) {  
            const config = resultData[0].value  
            // 保存到Redis  
            await redis.set(GLOBAL_CONFIG_KEY, JSON.stringify(config))  
            console.log('获取到全局配置并保存到Redis:', config)  
            return {  
                code: 0,  
                msg: '获取成功(DB)',  
                data: config  
            }  
        } else {  
            return {  
                code: 0,  
                msg: '配置不存在',  
                data: null  
            }  
        }  
    } catch (error) {  
        console.error('获取全局配置失败:', error)  
        return {  
            code: -1,  
            msg: '获取失败',  
            error: error.message  
        }  
    }  
},  

/**  
 * 更新全局配置  
 * @param {object} config 配置对象  
 * @returns {object} 返回更新结果  
 */  
async updateGlobalConfig(config) {  
    if (!config) {  
        return {  
            code: -1,  
            msg: '配置参数不能为空'  
        }  
    }  

    try {  
        const db = uniCloud.database()  
        const redis = uniCloud.redis()  

        const configRecord = await db.collection('config').where({  
            key: GLOBAL_CONFIG_KEY  
        }).get()  

        const resultData = configRecord.data || (configRecord.result && configRecord.result.data) || []  

        let result  
        if (resultData.length > 0) {  
            result = await db.collection('config').where({  
                key: GLOBAL_CONFIG_KEY  
            }).update({  
                value: config  
            })  
        } else {  
            result = await db.collection('config').add({  
                key: GLOBAL_CONFIG_KEY,  
                value: config  
            })  
        }  

        // 更新Redis缓存  
        await redis.set(GLOBAL_CONFIG_KEY, JSON.stringify(config))  

        console.log('更新全局配置成功(DB和Redis):', result)  
        return {  
            code: 0,  
            msg: '更新成功',  
            data: result  
        }  
    } catch (error) {  
        console.error('更新全局配置失败:', error)  
        return {  
            code: -1,  
            msg: '更新失败',  
            error: error.message  
        }  
    }  
}  

}

日志:

16:51:27.916 [本地运行]删除所有Redis键失败: uniCloud-tcb/cloudfunctions/aspack-redis/index.obj.js:216:11
16:51:27.916 [本地运行]TypeError [ERR_STREAM_NULLVALUES]: May not write null values to stream
16:51:27.916 [本地运行] at new NodeError (node:internal/errors:405:5)
16:51:27.916 [本地运行] at write
(node:_http_outgoing:873:11)
16:51:27.916 [本地运行] at ClientRequest.write (node:_http_outgoing:834:15)
16:51:27.916 [本地运行] at new Promise (<anonymous>)
16:51:27.916 [本地运行] at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
16:51:27.916 [本地运行] at async D:\software\HBuilderX.4.15.2024050802\HBuilderX\plugins\unicloud\share\ulib.js:1:177501
16:51:27.931 [本地运行][云对象:aspack-redis],调用方法:[delAllKeys],执行结果: {"code":-1,"msg":"删除失败","error":"May not write null values to stream"}

2025-07-21 16:54 负责人:无 分享
已邀请:
DCloud_uniCloud_CRL

DCloud_uniCloud_CRL

完整代码发一下

aspack001

aspack001 (作者) - 老程序猿

我之前发的是云函数的代码,下面是调用方的代码,在const aspackConfig = uniCloud.importObject('aspack-config')的时候会偶尔抛我说的错误,难道是我调用方法有问题?:

export async function syncServerConfig() {  
    try {  
        // 获取全局配置  
        const aspackConfig = uniCloud.importObject('aspack-config')  
        uni.debug("获取importObject aspack-config")  
        const configResult = await aspackConfig.getGlobalConfig()  
        uni.debug("调用aspack-config.getGlobalConfig")  
        uni.debug("获取到的configResult:", configResult);  
        if (configResult.code === 0 && configResult.data) {  
            Object.assign(store.state.app.config, configResult.data)  
            uni.debug(`服务端获取全局配置成功:${JSON.stringify(configResult.data)}`)  
            store.dispatch("app/syncConfig")  
        } else {  
            uni.error(`获取服务端全局配置失败:${JSON.stringify(configResult)}`);  
        }  

        let userId = getUserId()  
        if (userId === "noid") {  
            uni.debug("用户未登录,跳过同步用户配置");  
            return  
        }  

        const db = uniCloud.database()  
        const userRecord = await db.collection('extend_info_users').where({  
            user_id: userId  
        }).get()  

        // 兼容两种返回格式  
        const userData = userRecord.data || (userRecord.result && userRecord.result.data) || []  
        // 如果找到记录  
        let tmpConfig  
        if (userData.length > 0) {  
            const userInfo = userData[0]  
            tmpConfig = userInfo['config']  
            Object.assign(store.state.app.config, tmpConfig)  
            const xInfo = userInfo['x-info'];  
            uni.setStorageSyncByUser('x-info', xInfo);  
            store.state.app.isVipNow = isVipNow();  
            store.state.app.timeRefresh = Date.now();  
            uni.debug("用户是否VIP:", store.state.app.isVipNow);  
            uni.debug("找到用户配置:", tmpConfig)  

            // 检查并设置日志级别  
            if (store.state.app.config.log_level) {  
                uni.debug("设置日志级别为:", store.state.app.config.log_level);  
                try {  
                    logger.setLevel(store.state.app.config.log_level);  
                    uni.info("已从服务端配置设置日志级别为:", store.state.app.config.log_level);  
                } catch (error) {  
                    uni.error("设置日志级别失败:", error);  
                }  
            }  
            // 日志上传计数逻辑  
            if (typeof store.state.app.config.upload_logs_count === 'number' && store.state.app.config.upload_logs_count > 0) {  
                store.state.app.config.upload_logs = true;  
                store.state.app.config.upload_logs_count -= 1;  
                uni.info("upload_logs_count大于0,设置upload_logs为true,upload_logs_count减1,当前upload_logs_count:", store.state.app.config.upload_logs_count);  
                try {  
                    tmpConfig.upload_logs_count = store.state.app.config.upload_logs_count;  
                    await db.collection('extend_info_users').where({ user_id: userId }).update({  
                        ["config"]: tmpConfig  
                    });  
                    uni.info("已更新数据库中的upload_logs_count:", store.state.app.config.upload_logs_count);  
                } catch (error) {  
                    uni.error("更新数据库upload_logs_count出错:", error);  
                }  
            }  
            store.dispatch("app/syncConfig")  
        } else {  
            const userId = getUserId();  
            try {  
                await db.collection('extend_info_users').add({  
                    config: {  
                        upload_logs_count: 0  
                    },  
                    user_id: userId,  
                    create_time: Date.now()  
                });  
            } catch (error) {  
                uni.error("添加用户配置表时出错:", error);  
            }  
        }  

        if (store.state.app.config.upload_logs) {  
            uni.debug("需要上传日志,调用logger store的uploadLogs action");  
            try {  
                await store.dispatch('logger/uploadLogs');  
            } catch (error) {  
                uni.error("调用日志上传action失败:", error);  
            }  
        }  
    } catch (error) {  
        uni.error('同步配置信息出错:', error)  
    }  

    // 上传invokeCount和mmCount的sum统计数据  
    try {  
        const userId = getUserId();  
        if (userId !== "noid") {  
            // 获取ai-state中的invokeCount['sum']  
            const invokeCountSum = store.state.ai.invokeCount['sum'];  
            // 获取stastics中的mmCount['sum']  
            const mmCountSum = store.state.stastics.mmCount['sum'];  

            if (invokeCountSum !== undefined) {  
                // 使用uploader/addKey上传AI调用总次数统计  
                store.dispatch('uploader/addKey', {  
                    key: 'invokeCount',  
                    value: invokeCountSum  
                });  
                uni.debug("上传AI调用总次数统计:", invokeCountSum);  
            }  

            if (mmCountSum !== undefined) {  
                // 使用uploader/addKey上传多媒体使用统计  
                store.dispatch('uploader/addKey', {  
                    key: 'userinfo.mmCount.sum',  
                    value: mmCountSum  
                });  
                uni.debug("上传多媒体使用统计:", mmCountSum);  
            }  

            // 保存需要上传的键  
            store.dispatch('uploader/saveKeysNeedUploaded', {  
                key: 1  
            });  
        }  
    } catch (error) {  
        uni.error("上传统计数据出错:", error);  
    }  
}
aspack001

aspack001 (作者) - 老程序猿

我似乎找到原因了,我的云函数内存设置的128M,改成256M就好了。

要回复问题请先登录注册