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

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

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

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

148252 次浏览

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

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
}

基本上,当找不到文件时,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'

希望这个能帮上忙。

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

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

注意: 如果您的程序也删除文件,那么就会出现注释中提到的竞态条件。然而,如果您只写或覆盖文件,而不删除它们,那么这是完全没有问题的。

对于这些场景,我使用了一个立即调用的 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 {};
}
})();

尝试使用 异步代替,以避免阻塞 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
}
}

编码愉快!

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