部署在Heroku的Node.js应用出现Redis SETEX方法未定义错误求助
Node-Redis v4部署Heroku后出现TypeError: Cannot read properties of undefined (reading 'SETEX')错误
问题现象
将Node.js应用部署到Heroku后,触发Redis操作时抛出以下错误,导致系统无法正常运行:
2022-09-14T14:59:46.099027+00:00 app[web.1]: /app/dist/controller/contact/index.js:212 2022-09-14T14:59:46.099044+00:00 app[web.1]: return _redisClient.redisClient.SETEX(key, _config.REDIS_DEF_EXP_TIME, JSON.stringify(contacts)); 2022-09-14T14:59:46.099045+00:00 app[web.1]: ^ 2022-09-14T14:59:46.099045+00:00 app[web.1]: 2022-09-14T14:59:46.099046+00:00 app[web.1]: TypeError: Cannot read properties of undefined (reading 'SETEX') 2022-09-14T14:59:46.099046+00:00 app[web.1]: at _callee5$ (/app/dist/controller/contact/index.js:212:57) 2022-09-14T14:59:46.099046+00:00 app[web.1]: at tryCatch (/app/node_modules/regenerator-runtime/runtime.js:63:40) 2022-09-14T14:59:46.099047+00:00 app[web.1]: at Generator.invoke [as _invoke] (/app/node_modules/regenerator-runtime/runtime.js:294:22) 2022-09-14T14:59:46.099047+00:00 app[web.1]: at Generator.next (/app/node_modules/regenerator-runtime/runtime.js:119:21) 2022-09-14T14:59:46.099048+00:00 app[web.1]: at asyncGeneratorStep (/app/dist/controller/contact/index.js:22:103) 2022-09-14T14:59:46.099048+00:00 app[web.1]: at _next (/app/dist/controller/contact/index.js:24:194) 2022-09-14T14:59:46.099048+00:00 app[web.1]: at /app/dist/controller/contact/index.js:24:364 2022-09-14T14:59:46.099048+00:00 app[web.1]: at new Promise (<anonymous>) 2022-09-14T14:59:46.099049+00:00 app[web.1]: at /app/dist/controller/contact/index.js:24:97 2022-09-14T14:59:46.099049+00:00 app[web.1]: at /app/dist/controller/contact/index.js:226:30 2022-09-14T14:59:46.099049+00:00 app[web.1]: at /app/node_modules/mongoose/lib/model.js:5074:18 2022-09-14T14:59:46.099050+00:00 app[web.1]: at processTicksAndRejections (node:internal/process/task_queues:78:11)
环境配置
- Node.js Version: 16.x
- Node Redis Version: 4.0.2
- Platform: Heroku Cloud OS
现有Redis配置代码
import { createClient } from 'redis'; import { REDIS_URI } from '../config'; export let redisClient; (async () => { try { redisClient = createClient({ url: REDIS_URI }); redisClient.on("error", (err) => console.log("Redis Client Connection Error")); console.log("Redis cashe app database connected..."); await redisClient.connect(); } catch (error) { console.log('Redis app connection Error...', error); } })();
问题原因
- API版本不兼容:Node-Redis v4将v3及更早版本的大写Redis命令(如
SETEX)改为驼峰命名方法(setEx),直接调用SETEX会导致方法不存在。 - 初始化时序问题:当前用异步立即执行函数(IIFE)初始化
redisClient,若应用代码在初始化完成前调用,会导致redisClient为undefined。 - 调用层级错误:从错误日志
_redisClient.redisClient.SETEX可见,代码错误地对导入的redisClient再次访问redisClient属性,导致访问到undefined后调用方法失败。
解决方案
1. 修正Redis命令调用方式
将SETEX改为Node-Redis v4对应的驼峰方法setEx,同时修正调用层级:
// 错误写法 // return _redisClient.redisClient.SETEX(key, _config.REDIS_DEF_EXP_TIME, JSON.stringify(contacts)); // 正确写法(导入的是redisClient变量) return redisClient.setEx(key, _config.REDIS_DEF_EXP_TIME, JSON.stringify(contacts));
2. 确保客户端初始化完成后再使用
将初始化逻辑改为可等待的函数,在应用启动时等待Redis连接完成:
// redis配置文件修改 import { createClient } from 'redis'; import { REDIS_URI } from '../config'; export let redisClient; export async function initRedis() { try { redisClient = createClient({ url: REDIS_URI }); redisClient.on("error", (err) => console.error("Redis Client Connection Error:", err)); await redisClient.connect(); console.log("Redis cache app database connected..."); } catch (error) { console.error('Redis app connection Error...', error); process.exit(1); // 连接失败时退出应用 } }
在应用入口文件中调用并等待初始化:
// 入口文件如app.js import { initRedis } from './path/to/redis-config'; async function startApp() { await initRedis(); // 启动其他服务,如Express/Koa app.listen(process.env.PORT || 3000); } startApp();
3. 验证Heroku环境变量配置
确认Heroku上的REDIS_URI环境变量配置正确,可通过Heroku CLI查看:
heroku config:get REDIS_URI -a your-app-name
确保URI格式为redis://username:password@host:port,避免因地址错误导致客户端初始化失败。
内容的提问来源于stack exchange,提问作者Internazionaleauto
相关产品推荐
相关产品推荐

