171 votes

Comment capturer l'absence de fichier pour fs.readFileSync() ?

Dans node.js readFile() montre comment capturer une erreur, mais il n'y a pas de commentaire pour la méthode de capture. readFileSync() concernant la gestion des erreurs. Ainsi, si j'essaie d'utiliser readFileSync() alors qu'il n'y a pas de fichier, j'obtiens l'erreur suivante Error: ENOENT, no such file or directory .

Comment capturer l'exception levée ? La documentation ne précise pas quelles exceptions sont levées, donc je ne sais pas quelles exceptions je dois attraper. Je dois noter que je n'aime pas le style générique "attraper toutes les exceptions possibles" des instructions try/catch. Dans ce cas, je souhaite attraper l'exception spécifique qui se produit lorsque le fichier n'existe pas et que je tente d'effectuer le readFileSync.

Veuillez noter que je n'exécute les fonctions de synchronisation qu'au démarrage avant de servir les tentatives de connexion, donc les commentaires indiquant que je ne devrais pas utiliser les fonctions de synchronisation ne sont pas nécessaires :-)

254voto

Golo Roden Points 10272

En gros, fs.readFileSync lance une erreur lorsqu'un fichier n'est pas trouvé. Cette erreur provient de la Error et lancé à l'aide de throw donc la seule façon de l'attraper est avec un try / catch bloc :

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
}

Malheureusement, vous ne pouvez pas détecter l'erreur qui a été lancée en regardant simplement sa chaîne de prototypes :

if (err instanceof Error)

est le mieux que vous puissiez faire, et cela sera vrai pour la plupart (sinon toutes) des erreurs. C'est pourquoi je vous suggère d'utiliser la méthode code et vérifiez sa valeur :

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

De cette façon, vous ne traitez que cette erreur spécifique et rejetez toutes les autres erreurs.

Alternativement, vous pouvez aussi accéder à l'erreur message pour vérifier le message d'erreur détaillé, qui dans ce cas est :

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

J'espère que cela vous aidera.

31voto

Je préfère cette façon de procéder. Vous pouvez vérifier si le fichier existe de manière synchrone :

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

Remarque : si votre programme supprime également des fichiers, il y a une condition de course comme indiqué dans les commentaires. Si toutefois vous ne faites qu'écrire ou écraser des fichiers, sans les supprimer, alors tout va bien.

17voto

loganfsmyth Points 25483

Vous devez attraper l'erreur et ensuite vérifier de quel type d'erreur il s'agit.

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
}

6voto

sdgfsdh Points 868

J'utilise une lambda immédiatement invoquée pour ces scénarios :

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

async version :

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

1voto

ViktorKrpn Points 31

Le mécanisme JavaScript try catch ne peut pas être utilisé pour intercepter les erreurs générées par les API asynchrones. Une erreur fréquente pour les débutants est d'essayer d'utiliser throw à l'intérieur d'un callback de type error-first :

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

Cela ne fonctionnera pas car la fonction de rappel passée à fs.readFile() est appelée de manière asynchrone. Le temps que la fonction de rappel soit appelée, le code environnant, y compris le bloc try catch, sera déjà sorti. Lancer une erreur dans le callback peut faire planter le processus Node.js dans la plupart des cas. Si les domaines sont activés, ou si un gestionnaire a été enregistré avec process.on('uncaughtException'), de telles erreurs peuvent être interceptées.

référence : https://nodejs.org/api/errors.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X