node-rdkafka报eventType.toBuffer is not a function错误如何解决
问题现象
在Visual Studio中运行基于node-rdkafka编写的Kafka生产者代码时,抛出如下运行时错误:
TypeError: eventType.toBuffer is not a function
at queueRandomMessage
涉及的生产者业务代码如下:
const Kafka = require('node-rdkafka'); const eventType = require('../eventType.js'); const stream = Kafka.Producer.createWriteStream({ 'metadata.broker.list': 'localhost:9092' }, {}, { topic: 'test' }); stream.on('error', (err) => { console.error('Error in our kafka stream'); console.error(err); }); function queueRandomMessage() { const category = getRandomAnimal(); const noise = getRandomNoise(category); const event = { category, noise }; const success = stream.write(eventType.toBuffer(event)); if (success) { console.log(`message queued (${JSON.stringify(event)})`); } else { console.log('Too many messages in the queue already..'); } } function getRandomAnimal() { const categories = ['CAT', 'DOG']; return categories[Math.floor(Math.random() * categories.length)]; } function getRandomNoise(animal) { if (animal === 'CAT') { const noises = ['meow', 'purr']; return noises[Math.floor(Math.random() * noises.length)]; } else if (animal === 'DOG') { const noises = ['bark', 'woof']; return noises[Math.floor(Math.random() * noises.length)]; } else { return 'silence..'; } } setInterval(() => { queueRandomMessage(); }, 3000);
依赖的eventType.js(基于avsc库定义Avro序列化Schema)代码如下:
const avro = require('avsc'); module.export = avro.Type.forSchema({ type: 'record', fields: [ { name: 'category', type: { type: 'enum', symbols: ['DOG', 'CAT'] } }, { name: 'noise', type: 'string', } ] });
错误根因
报错本质是导入的eventType不是预期的avsc Type实例,不存在toBuffer方法。问题出在eventType.js的CommonJS导出语法写错:Node.js CommonJS规范中模块导出的固定属性是*module.exports*,代码里写成了module.export(末尾少了s),导致require拿到的是未挂载正确导出值的模块对象,自然调用不了toBuffer方法。
修复步骤
- 定位导出问题:可以在
queueRandomMessage函数第一行加console.log(eventType)打印导入值,运行后会发现输出不是avsc生成的Schema实例,即可确认是模块导入环节出错。 - 修正导出语法:打开
eventType.js,把module.export改为module.exports,修正后的完整代码如下:
const avro = require('avsc'); module.exports = avro.Type.forSchema({ type: 'record', fields: [ { name: 'category', type: { type: 'enum', symbols: ['DOG', 'CAT'] } }, { name: 'noise', type: 'string', } ] });
- 可选防御性校验:可以在生产者代码头部require语句之后加校验逻辑,提前捕获Schema加载异常,避免运行时才抛出方法不存在的错误:
if (!eventType || typeof eventType.toBuffer !== 'function') { throw new Error('Avro Schema加载失败,请检查eventType.js导出配置'); }
修复验证
修正后重新运行代码,控制台会每隔3秒打印消息入队成功的日志,不再抛出toBuffer is not a function的错误,生产者可以正常将Avro序列化后的消息写入Kafka集群。
内容的提问来源于stack exchange,提问作者Diani Putri
相关产品推荐
相关产品推荐

