166

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

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

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

4

6 回答 6

246

基本上,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'

希望这可以帮助。

于 2013-01-18T04:10:46.810 回答
30

我更喜欢这种处理方式。您可以检查文件是否同步存在:

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(file, 'utf-8');
}

注意:如果您的程序还删除了文件,则如注释中所述,这具有竞争条件。但是,如果您只写入或覆盖文件而不删除它们,那么这完全没问题。

于 2015-09-27T04:33:55.390 回答
17

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

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
}
于 2013-01-18T04:06:56.030 回答
6

对于这些场景,我使用立即调用的 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 {};
  }
})();
于 2017-11-28T12:30:36.273 回答
1

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

于 2020-06-26T08:26:19.547 回答
-1

尝试使用Async来避免阻塞 NodeJS 的唯一线程。检查这个例子:

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;
}

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

const anyOtherFun = async () => {
  try {
    const fileContent = await readContentFile('my-file.txt');
  } catch (err) {
    // Here you get the error when the file was not found,
    // but you also get any other error
  }
}

快乐编码!

于 2019-12-15T03:44:58.373 回答