Nodejs 关于node_redis的错误处理问题,监听error事件不起效,并由此引申出一些异常处理的问题。

Nodejs 关于node_redis的错误处理问题,监听error事件不起效,并由此引申出一些异常处理的问题。

项目用的express+node_redis。。

var redis_client = redis.createClient(redis_port, redis_ip ); //catch error event create by redis connection redis_client.on(“error”, function (err) { console.log("Error: "+err.stack); });

这里已经监听了error事件。然后启动项目。redis的连接建立。这时候我把redis_server的进程kill掉。异常依然抛出,然后程序退出。。

events.js:72 throw er; // Unhandled ‘error’ event ^ Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED at RedisClient.on_error (/opt/N-chat/node_modules/redis/index.js:185:24) at Socket.stream.on.self.should_buffer (/opt/N-chat/node_modules/redis/index.js:95:14) at Socket.EventEmitter.emit (events.js:95:17) at Socket._destroy.self._writableState.errorEmitted (net.js:440:14) at process._tickCallback (node.js:419:13) Process finished with exit code 8 按照我的设想。。这个监听不是应该类似try catch里面的catch作用??如果我理解有误,请问怎么处理这种异常。。

PS: 网上查过翻过不少github上的项目,但是大部分项目都感觉是自己研究的性质。基本没看到完整的异常容错处理。 因为自己初学不久,所以我想是不是我错过了什么大家 默认的常识之类。下面再提一点小问题验证下: 官网的一个例子: app.param(‘user’, function(req, res, next, id){ User.find(id, function(err, user){ if (err) { next(err); } else if (user) { req.user = user; next(); } else { next(new Error(‘failed to load user’)); } }); }); next是一个函数,那就是说在所有的方法里面我都可以把它当作一个参数传递进去,然后next()作用相当于显式调用事件队列里面的下一个事件,并且把err传递到下一个事件,如果是这样理解怎么确定下一个就是异常处理的事件? 然后就是err,这个参数怎么理解。。如果这是单纯的js中的error对象(我断点看过这个对象的结构,是跟error对象应该是一样的。)。不明白的是整个error机制。是不是默认所有回调的第一个参数都是err??如果是的话,这个err能等效于try catch中的catch(err)这个动作吗?意思就是只要显式在function的参数声明这个参数就可以不用再捕捉回调函数体内的异常了?

可能问题不一定是node的问题,有可能是js的问题。。由于我自己也是js基础较差,只能尽量描述清楚我的问题~~先感谢你把这么长的问题看完。。希望能得到大家的指点~~


8 回复

针对您的问题,主要涉及到如何正确处理Redis客户端的错误事件以及Node.js中的异常处理机制。以下是详细的解答和示例代码:

解决Redis客户端错误事件未触发的问题

在Node.js中使用node_redis模块时,如果Redis服务器意外关闭或无法连接,Redis客户端会触发error事件。然而,有时这些事件可能不会按预期被触发。这可能是由于某些版本的node_redis或其他环境因素导致的。

示例代码

const redis = require('redis');
const redis_client = redis.createClient(redis_port, redis_ip);

// 监听error事件
redis_client.on('error', function (err) {
    console.error("Redis Error: " + err.message);
});

// 设置超时时间以确保连接失败时能够及时检测到错误
redis_client.on('ready', function () {
    console.log("Redis client ready");
});

redis_client.on('reconnecting', function () {
    console.log("Reconnecting to Redis...");
});

redis_client.on('end', function () {
    console.log("Redis client disconnected");
});

Node.js中的异常处理机制

在Node.js中,错误通常通过回调函数的第一个参数来传递。例如,在数据库查询或文件读取操作中,如果发生错误,通常会将错误对象作为回调函数的第一个参数传递给回调函数。

示例代码

app.param('user', function(req, res, next, id) {
    User.find(id, function(err, user) {
        if (err) {
            // 将错误传递给下一个中间件或错误处理中间件
            return next(err);
        } else if (!user) {
            // 如果用户不存在,创建一个新的错误并传递给下一个中间件
            return next(new Error('Failed to load user'));
        }
        req.user = user;
        next(); // 继续执行下一个中间件
    });
});

错误处理中间件

为了更好地处理应用程序中的错误,可以定义专门的错误处理中间件。这些中间件通常位于路由中间件之后,并接收四个参数(err, req, res, next)。

示例代码

app.use(function(err, req, res, next) {
    console.error(err.stack);
    res.status(500).send('Something broke!');
});

总结

  • Redis错误处理:确保正确配置Redis客户端的事件监听器,包括errorreadyreconnectingend事件。
  • Node.js异常处理:错误通常通过回调函数的第一个参数传递,可以在回调函数中使用next(err)将错误传递给错误处理中间件。
  • 错误处理中间件:定义专门的错误处理中间件来捕获和处理应用程序中的错误。

希望这些信息能帮助您解决遇到的问题,并提高您的Node.js应用程序的健壮性。


在线等解答。。如果是问题提的不好的地方大家可以指出。我再尝试修改一下啊~~

redis那里的问题得去看redis这个库的代码是怎么回事。

你说的这个我已经看过。。有个不明白的地方。就是domain跟socket.io怎么结合。。是在domain的.run里面再执行socket.io的create事件,然后开始通信等等,还是说先执行socket.on()监听,在回调function里面嵌入domain.run??

此文章已经看过。收获很大~!之前一直用的三个参数怪不得不起效。。目前异常处理这块还差一个。。就是socket.io的。。我发现他监听的error事件只是对于socket连接本身的异常监听。。类似socket.on(‘event’,function(){…})这个函数里面的异常是无法监听的。。我想请问下如果我想做个全局的处理。专门处理这个socket的回调函数里面的异常可以怎么做?

根据你的描述,你希望了解如何正确处理 node_redis 中的错误事件,并讨论如何处理异步操作中的异常。在 Node.js 中,错误事件通常需要通过监听 error 事件来处理。如果错误事件没有被处理(即未绑定错误处理器),Node.js 会将其视为未捕获的异常,导致程序退出。

示例代码

const redis = require('redis');
const express = require('express');
const app = express();

const redis_client = redis.createClient(redis_port, redis_ip);

// 监听错误事件
redis_client.on('error', (err) => {
    console.error('Redis Client Error:', err);
});

// 示例路由
app.get('/', (req, res) => {
    redis_client.get('some_key', (err, reply) => {
        if (err) {
            console.error('Redis GET Error:', err);
            return res.status(500).send('Internal Server Error');
        }
        res.send(reply || 'Key not found');
    });
});

// 启动应用
app.listen(port, () => {
    console.log(`Server running on port ${port}`);
});

解释

  1. 监听 error 事件

    • 你需要确保每个异步操作都有错误处理逻辑。redis_client.on('error', ...) 绑定了错误处理器,但如果你的 Redis 连接本身出错,例如网络问题或服务不可达,你也需要确保在连接创建时就绑定错误处理器。
  2. 处理异步操作中的错误

    • redis_client.get 调用中,第一个参数 err 是可能发生的错误。你需要检查它并适当地处理,比如返回错误信息给客户端。
  3. 错误传播

    • 使用 next(err) 可以将错误传递给 Express 的错误处理中间件。如果你使用 Express 框架,可以在最后定义一个错误处理中间件来捕获所有未处理的错误。

补充说明

  • next 参数:在 Express 中,next 函数用于传递控制到下一个中间件或路由处理器。如果 next(err) 被调用,Express 会自动将错误传递给错误处理中间件。

  • err 参数:在 Node.js 中,很多回调函数的第一参数通常是错误对象,表示该异步操作是否成功。你可以将 errtry-catch 中的 catch 语句进行类比,但要注意它们的作用域和生命周期不同。

希望这些信息能帮助你更好地理解 Node.js 中的错误处理机制。

回到顶部