如何捕获fs.readFileSync()没有文件?

时间:2013-01-18 02:50:31

标签: node.js error-handling try-catch

在node.js readFile()中显示了如何捕获错误,但是readFileSync()函数没有关于错误处理的注释。因此,如果我在没有文件时尝试使用readFileSync(),则会收到错误Error: ENOENT, no such file or directory

如何捕获抛出的异常? doco没有说明抛出了什么异常,所以我不知道我需要捕获哪些异常。我应该注意到,我不喜欢通用的'捕获每一个可能的异常'样式的try / catch语句。在这种情况下,我希望捕获文件不存在时发生的特定异常,并尝试执行readFileSync。

请注意,我只在启动服务连接尝试之前执行同步功能,因此不需要我不应该使用同步功能的评论:-)

6 个答案:

答案 0 :(得分:171)

基本上,fs.readFileSync在找不到文件时会抛出错误。此错误来自Error原型并使用throw抛出,因此捕获的唯一方法是使用try / catch块:

var fileContents;
try {
  fileContents = fs.readFileSync('foo.bar');
} catch (err) {
  // Here you get the error when the file was not found,
  // but you also get any other error
}

不幸的是,通过查看其原型链,您无法检测到抛出了哪个错误:

if (err instanceof Error)

是你能做的最好的事情,对于大多数(如果不是全部)错误都是如此。因此,我建议您使用code属性并检查其值:

if (err.code === 'ENOENT') {
  console.log('File not found!');
} else {
  throw err;
}

这样,您只处理此特定错误并重新抛出所有其他错误。

或者,您也可以访问错误的message属性来验证详细的错误消息,在这种情况下是:

ENOENT, no such file or directory 'foo.bar'

希望这有帮助。

答案 1 :(得分:18)

虽然接受的解决方案没问题,但我找到了一种更好的处理方法。您可以检查文件是否同步存在:

var file = 'info.json';
var content = '';

// Check that the file exists locally
if(!fs.existsSync(file)) {
  console.log("File not found");
}

// The file *does* exist
else {
  // Read the file and do anything you want
  content = fs.readFileSync(this.local, 'utf-8');
}

答案 2 :(得分:9)

您必须捕获错误,然后检查它是什么类型的错误。

try {
  var data = fs.readFileSync(...)
} catch (err) {
  // If the type is not what you want, then just throw the error again.
  if (err.code !== 'ENOENT') throw err;

  // Handle a file-not-found error
}

答案 3 :(得分:3)

我在这些场景中使用了一个立即调用的lambda:

const config = (() => {
  try {
    return JSON.parse(fs.readFileSync('config.json'));
  } catch (error) {
    return {};
  }
})();

async版本:

const config = await (async () => {
  try {
    return JSON.parse(await fs.readFileAsync('config.json'));
  } catch (error) {
    return {};
  }
})();

答案 4 :(得分:0)

尝试使用异步来避免阻塞NodeJS仅有的线程。检查此示例:

with df as (
select  i1.Customerid, t.milliseconds, Rank() over(partition by i1.Customerid 
                                                    order by t.milliseconds asc) as Rank
from invoices i1, invoice_items i2, tracks t
where i1.invoiceid = i2.InvoiceLineId
and i2.TrackId = t.TrackId) 
select Customerid, milliseconds
from df
where Rank < 5

having count(*) > 5;

以后可以将此异步功能与其他任何功能的try / catch一起使用:

const util = require('util');
const fs = require('fs');
const path = require('path');
const readFileAsync = util.promisify(fs.readFile);

const readContentFile = async (filePath) => {
  // Eureka, you are using good code practices here!
  const content = await readFileAsync(path.join(__dirname, filePath), {
    encoding: 'utf8'
  })
  return content;
}

快乐编码!

答案 5 :(得分:0)

JavaScript try…catch机制不能用于拦截异步API生成的错误。对于初学者来说,常见的错误是尝试在错误优先的回调中使用throw:

// THIS WILL NOT WORK:
const fs = require('fs');

try {
  fs.readFile('/some/file/that/does-not-exist', (err, data) => {
    // Mistaken assumption: throwing here...
    if (err) {
      throw err;
    }
  });
} catch (err) {
  // This will not catch the throw!
  console.error(err);
}

这将不起作用,因为传递给fs.readFile()的回调函数是异步调用的。到回调被调用时,周围的代码(包括try…catch块)将已经退出。在大多数情况下,在回调中引发错误可能会使Node.js进程崩溃。如果启用了域,或者已向process.on('uncaughtException')注册了处理程序,则可以拦截此类错误。

参考: https://nodejs.org/api/errors.html