为什么Nodejs错误日志写不进去,app.use or app.error

为什么Nodejs错误日志写不进去,app.use or app.error

我在另外一个webapp里用了app.error可以正常写入错误日志,这个用app.use却写不进去 但是下面这个app.use(function (err, req, res, next)如果改成app.error又会报错 var error_logfile = fs.WriteStream(app_config.error_logfile, { flags: ‘a’ }); var public_dir = app_config.public_dir; app.configure(‘development’, function () { app.use(express.static(public_dir)); if (app_config.error_log) { //error_log为true app.use(function (err, req, res, next) { meta += ‘[’ + new Date() + '] ’ + req.url + ‘\n’; error_logfile.write(meta + err.stack + ‘\n’); next(); }) } else { app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); } app.use(express.bodyParser()); });


5 回复

为什么Node.js错误日志写不进去,app.use or app.error

在Node.js中处理错误日志时,经常会遇到一些常见的问题。你提到的情况是使用app.use可以正常写入错误日志,但换成app.error时会报错。这主要是因为app.error已经不再被Express框架支持,而应该使用app.use来处理错误中间件。

示例代码

首先,确保你正确地安装了必要的依赖包,例如expressfs(文件系统模块):

npm install express

然后,在你的应用中设置错误处理中间件。这里是一个简单的示例:

const express = require('express');
const fs = require('fs');
const path = require('path');

const app = express();

// 配置错误日志文件路径
const app_config = {
    public_dir: path.join(__dirname, 'public'),
    error_logfile: path.join(__dirname, 'error.log'),
    error_log: true
};

// 创建错误日志文件流
const error_logfile = fs.createWriteStream(app_config.error_logfile, { flags: 'a' });

// 设置开发环境下的中间件
app.configure('development', function () {
    app.use(express.static(app_config.public_dir));

    if (app_config.error_log) {
        app.use(function (err, req, res, next) {
            const meta = `[${new Date()}] ${req.url}\n`;
            error_logfile.write(meta + err.stack + '\n');
            next();
        });
    } else {
        app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
    }

    app.use(express.json()); // 解析JSON请求体
    app.use(express.urlencoded({ extended: true })); // 解析URL编码的请求体
});

// 定义一个错误路由以触发错误处理
app.get('/error', (req, res) => {
    throw new Error('This is a test error');
});

// 启动服务器
const port = process.env.PORT || 3000;
app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
});

解释

  1. 错误日志文件流

    • 使用fs.createWriteStream创建一个可追加模式的日志文件流。
  2. 错误处理中间件

    • app.use函数中定义错误处理中间件,接收四个参数:err(错误对象)、req(请求对象)、res(响应对象)和next(下一步回调函数)。
    • 在中间件中记录错误信息到日志文件,并调用next()传递控制权给下一个中间件或路由处理程序。
  3. 错误路由

    • 定义一个错误路由/error,用于测试错误处理是否生效。

通过这种方式,你可以确保错误日志能够被正确地写入文件。注意不要使用已被废弃的app.error方法,而是使用app.use来处理错误中间件。


app.error 已经 deprecated 了。 会不会跟你 app.use 的位置有关?放在所有 router 最后试试。

是的,app.error不再用了,所以换成use,但错误日志死活写不进去

恩,是我的位置写错了,访问日志写在前面,错误日志需要放在router后面~~

从描述来看,问题可能出在 express.errorHandler 和自定义错误处理中间件的使用方式上。在较新版本的 Express 中,app.error 已被弃用,应该使用 app.use() 来注册错误处理中间件。

在你的代码中,app.use() 方法中的错误处理中间件需要放在所有路由中间件之后。如果你的 app.use() 写在其他中间件之前,它可能不会捕获到错误。

以下是一些可能有用的建议和改进:

  1. 确保错误处理中间件在最后: 确保错误处理中间件位于所有路由和普通中间件之后。错误处理中间件必须是最后一个中间件。

  2. 使用最新版本的 Express: 如果你使用的是较新的 Express 版本,可以考虑使用 express.json()express.urlencoded() 替代 express.bodyParser()

  3. 正确设置错误处理中间件: 确保错误处理中间件接收四个参数 (err, req, res, next)

以下是修改后的代码示例:

var fs = require('fs');
var express = require('express');
var app_config = require('./config'); // 假设你有一个配置文件

var error_logfile = fs.createWriteStream(app_config.error_logfile, { flags: 'a' });
var public_dir = app_config.public_dir;

var app = express();

app.configure('development', function () {
    app.use(express.static(public_dir));

    if (app_config.error_log) {     // error_log为true
        app.use(function (err, req, res, next) {
            var meta = '[' + new Date() + '] ' + req.url + '\n';
            error_logfile.write(meta + err.stack + '\n');
            next();
        });
    } else {
        app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
    }

    app.use(express.json()); // 使用最新版本的Express
    app.use(express.urlencoded()); // 使用最新版本的Express

    // 定义一个错误来测试
    app.get('/error', function (req, res) {
        throw new Error('This is a test error');
    });

    // 确保错误处理中间件在最后
    app.use(function (err, req, res, next) {
        console.error(err.stack);
        res.status(500).send('Something broke!');
    });
});

// 启动服务器
app.listen(3000, function () {
    console.log('Server started on port 3000');
});

通过这种方式,你可以确保错误处理中间件在最后,并且能够正确捕获并记录错误。

回到顶部