Nodejs嵌套函数调用Postgres查询返回空结果故障排查
问题原因分析
1. 参数传递错误(最高概率)
你在外层query方法中已经拼接好了完整的SQL语句,但调用_queryReplicaDB时传的是原始的queryInfo对象,不是拼接好的SQL字符串。而_queryReplicaDB里直接把入参(实际是Query类型对象)传给了pool.query,等于把错误的参数传给了数据库驱动,自然查询结果不符合预期,返回空rows。
代码细节验证:
外层query方法中拼接的SQL完全没有被使用,传参错误:
static async query(queryInfo: Query): Promise<any> { // 拼接了正确的完整SQL,但完全没有用到这个变量 const query = `select * from ${queryInfo.name} ${queryInfo.arguments} as info;`; try { // 传的是原始queryInfo对象,不是拼接好的SQL字符串 return this._queryReplicaDB(queryInfo); } catch (err) { console.log("err", err); throw err; } }
_queryReplicaDB中直接把入参当成SQL执行,参数类型不匹配:
static async _queryReplicaDB(query: Query): Promise<any> { // 省略连接池选取逻辑 const response = await pool.query(query); // 此处query是Query对象,不是数据库驱动识别的SQL字符串 // 省略后续逻辑 }
你直接在query方法内执行、或者把随机逻辑写在query方法内能正常运行,就是因为这些场景下都是把拼接正确的SQL字符串传给了pool.query。
2. 其他次要排查点
- 静态方法
this指向异常:如果_queryReplicaDB被提取到其他上下文执行过,可能导致this指向丢失,拿不到正确的_connection_pools数组,可以加日志打印this._connection_pools确认是否和预期一致。 - 重试逻辑边界问题:如果所有连接池都查询失败,你当前的代码中
response会是undefined,直接访问response.rows[0].info会抛出错误,不过你描述的是rows为空不是报错,该场景概率较低。
修复方案
调整参数传递逻辑,把拼接好的SQL字符串传给_queryReplicaDB即可:
static async query(queryInfo: Query): Promise<any> { const sql = `select * from ${queryInfo.name} ${queryInfo.arguments} as info;`; try { // 传拼接好的SQL字符串,而非原始queryInfo return this._queryReplicaDB(sql); } catch (err) { console.log("err", err); throw err; } } // 调整入参类型为string static async _queryReplicaDB(sql: string): Promise<any> { const randomNumber = Math.floor(Math.random() * this._connection_pools.length); const pool = this._connection_pools[randomNumber]; try { const response = await pool.query(sql); return response.rows[0].info; } catch { let response; for (let i = 0; i < this._connection_pools.length; i++) { const pool = this._connection_pools[i]; try { response = await pool.query(sql); break; } catch { console.log("Error in Pool index: ", i); } } // 补充边界判断,避免所有连接池都失效时报错 if (!response) throw new Error("All database connection pools are unavailable"); return response.rows[0].info; } }
内容的提问来源于stack exchange,提问作者Code Guru
相关产品推荐
相关产品推荐

