【问题标题】:How to properly deal with errors while using NodeJS's readline module使用 NodeJS 的 readline 模块时如何正确处理错误
【发布时间】:2021-02-17 00:04:22
【问题描述】:

我正在尝试逐行读取和处理文件。我想使用 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 }) 

没有成功。

【问题讨论】:

    标签: node.js async-await


    【解决方案1】:

    try/catch 只捕获同步错误。所以它不会从rl.on() 内部捕获任何东西。执行await once() 只是在执行console.log('File processed.'); 之前等待流rl,但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()
    

    【讨论】:

      猜你喜欢
      • 2016-03-19
      • 1970-01-01
      • 2020-01-09
      • 1970-01-01
      • 1970-01-01
      • 2019-04-23
      • 2011-12-14
      • 2020-10-02
      • 2019-05-25
      相关资源
      最近更新 更多