You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Morgan自定义异步日志函数中正确返回值?

问题解决:Morgan中使用async函数返回"[object Promise]"的处理方案

问题根源

Morgan的自定义格式函数要求同步返回字符串,而async函数默认返回Promise对象,当Morgan尝试将这个Promise转为字符串时,就会输出"[object Promise]"。不能直接在format函数中使用async/await,因为Morgan不支持处理异步返回值。

解决方案1:异步逻辑与格式返回分离(IIFE方式)

保持format函数为同步,内部用立即执行异步函数(IIFE)处理日志存储,不阻塞Morgan的格式输出:

const log = require("./queries/logQuery");
const moment = require('moment');
const morgan = require('morgan');

const custom = (tokens, req, res) => {
    if(req.session){
        // 用IIFE执行异步日志存储,不影响Morgan的同步返回
        (async () => {
            const date = moment().locale('id').format('DD-MM-YYYY HH:mm:ss');
            const usr = req.session.superadmin || req.session.user;
            const method = tokens.method(req, res);
            const endpoint = tokens.url(req, res);
            const statusCode = tokens.status(req, res);

            try {
                await log.addLog(date, usr, method, endpoint, statusCode);
            } catch (err) {
                console.error('日志存储失败:', err);
            }
        })();

        return [
            tokens.method(req, res),
            tokens.url(req, res),
            tokens.status(req, res),
            tokens.res(req, res, 'content-length'), '-',
            tokens['response-time'](req, res), 'ms'
        ].join(' ')
    }
}

router.use(morgan(custom))

解决方案2:拆分中间件(更清晰的架构)

单独写一个中间件处理异步日志存储,Morgan只负责同步输出格式:

const log = require("./queries/logQuery");
const moment = require('moment');
const morgan = require('morgan');

// 异步日志存储中间件:监听响应完成事件
router.use((req, res, next) => {
    res.on('finish', async () => {
        if(req.session){
            const date = moment().locale('id').format('DD-MM-YYYY HH:mm:ss');
            const usr = req.session.superadmin || req.session.user;
            const method = req.method;
            const endpoint = req.originalUrl;
            const statusCode = res.statusCode;

            try {
                await log.addLog(date, usr, method, endpoint, statusCode);
            } catch (err) {
                console.error('日志存储失败:', err);
            }
        }
    });
    next();
});

// Morgan仅处理日志格式输出
router.use(morgan(':method :url :status :res[content-length] - :response-time ms'));

关键说明

  • 两种方案都避免了让Morgan的format函数返回Promise,彻底解决[object Promise]问题
  • 异步操作需添加错误捕获,避免出现未处理的Promise拒绝报错

内容的提问来源于stack exchange,提问作者ipeenk downloader

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 15:45:34