node.js - 使用 NodeJS 的 readline 模块时如何正确处理错误
问题描述
我正在尝试逐行读取和处理文件。我想使用 try / catch 异步模式来做到这一点。下面是一个直接从 NodeJS 文档中提取的关于如何使用 readline 模块的示例。
const { once } = require('events');
const { createReadStream } = require('fs');
const { createInterface } = require('readline');
(async function processLineByLine() {
try {
const rl = createInterface({
input: createReadStream('big-file.txt'),
crlfDelay: Infinity
});
rl.on('line', (line) => {
// Process the line.
});
await once(rl, 'close');
console.log('File processed.');
} catch (err) {
console.error(err);
}
})();
我认为这await once
部分让我陷入了一个循环。如果在解析行时遇到错误,我想做什么:
rl.on('line', (line) => {
try {
// Process the line. maybe error from parsing?
JSON.parse(line)
} catch ( error ) {
throw new Error("error while attempting to process json.")
}
});
可以访问外部 try / catch 块中新抛出的错误,例如:
console.log('File processed.');
} catch (err) {
console.error(err);
// should see "error while attempting to process json."
}
})();
到目前为止,firebase 函数在没有到达外部 try/catch 块的情况下崩溃。我尝试将错误事件侦听器添加到 readline 流中,例如:
rl.on("error", () => { // throw error here })
没有成功。
解决方案
try/catch 只捕获同步错误。所以它不会从里面抓到任何东西rl.on()
。在执行await once()
之前只是等待流 rl 来执行,console.log('File processed.');
但是try{}catch(e){}
已经执行了,所以任何错误都不能被捕获。
rl.on('error', () => {}
只会从 rl 流本身捕获错误,因此即使发生错误createReadStream('big-file.txt')
也不会被捕获(并且由于它是异步的,最终的 catch(e) 也不会捕获它)。
要捕获 中发生的任何错误,rl.on('line ....'
解决方案之一是拒绝该错误。async/await 函数中被拒绝的错误将像在同步流中一样被 catch()。
一个例子
async function processLineByLine() {
try{
async function run() {
const rs = createReadStream(__filename)
// otherwise createReadStream() err are not handled
rs.on('error', () => {
console.log('HandleReadStreanErr')
})
const rl = createInterface({
input: rs,
crlfDelay: Infinity
})
return new Promise((resolve, reject) => {
rl.on('line', (line) => {
try {
throw new Error("error while attempting to process json.")
resolve(console.log(line.toString()))
} catch(e) {
reject(e)
}
})
})
// handle specificaly the rl stream error
rl.on('error', () => console.log('errr rl stream'))
await once(rl, 'close');
console.log('File processed.');
}
// await the overall execution for the catch() to wait
await run()
} catch(e) {
// only rejected err reach here or the one happening synchronously
console.error('eeeeeee')
}
}
processLineByLine()
我个人喜欢在靠近它们发生的地方处理每个错误。但是有些人喜欢用一个错误处理程序在一个地方处理它们。在这种情况下,我们可以用一个 Promise 包装整个执行
async function processLineByLine() {
try{
async function run() {
return new Promise(async (resolve, reject) => {
const rs = createReadStream('khg.jk')
rs.on('error', () => {
reject('HandleReadStreanErr')
})
const rl = createInterface({
input: rs,
crlfDelay: Infinity
})
rl.on('line', (line) => {
try {
// uncomment following err
// throw new Error("error while attempting to process json.")
resolve(console.log(line.toString()))
} catch(e) {
reject(e)
}
})
rl.on('error', () => reject('errr rl stream'))
await once(rl, 'close');
console.log('File processed.');
})
}
await run()
} catch(e) {
console.error('set error handler: ', e)
}
}
processLineByLine()
推荐阅读
- android - 如何从传感器 TYPE_ROTATION_VECTOR 获得的 3D 矩阵计算 2D 旋转(锁定一个轴旋转)
- matlab - 为什么对于这个看似有效的变换矩阵,我会收到警告 MATLAB:hg:DiceyTransformMatrix?
- python-3.x - 当我用 utf-8 读取文件时,.find() 不起作用
- php - 将数据插入特定表,但在 Lumen 5.8 的另一个表中出现错误
- windows - Windows Server 2012 上 API 和 DB 的奇怪缓存问题
- python - 使用 Python 的 pandas 循环中的下 n 个值
- php - 在wordpress自定义帖子中按分类获取页面列表
- tomcat - Tomcat 8.5.42 - 向服务器发布请求给出错误 403
- python-3.x - 从文件python 3读取时返回
- bash - 如何从 AIX 上的文件中重写某些行?