Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🟢
Web 12 min intermediaire

Les erreurs a eviter en Node.js

Sommaire

Erreur 1 : Callback Hell

Le problème

Callback Hell est une situation où les callbacks imbriqués rendent le code difficile à lire et à maintenir. Voici un exemple :

fs.readFile('file1.txt', 'utf8', function(err, data1) {
    if (err) throw err;
    fs.readFile('file2.txt', 'utf8', function(err, data2) {
        if (err) throw err;
        fs.readFile('file3.txt', 'utf8', function(err, data3) {
            if (err) throw err;
            console.log(data1 + data2 + data3);
        });
    });
});

Pourquoi c'est une erreur

  • Performance : Les callbacks imbriqués peuvent entraîner un problème de performance en bloquant l'événement loop.
  • Sécurité : L'absence d'erreur handling peut rendre le code vulnérable à des attaques.
  • Maintenabilité : Le code est difficile à lire et à modifier, ce qui augmente les risques de bugs.

La solution

Utilisez des promesses ou async/await pour simplifier le code :

async function readFileSequentially() {
    try {
        const data1 = await fs.promises.readFile('file1.txt', 'utf8');
        const data2 = await fs.promises.readFile('file2.txt', 'utf8');
        const data3 = await fs.promises.readFile('file3.txt', 'utf8');
        console.log(data1 + data2 + data3);
    } catch (err) {
        console.error(err);
    }
}

readFileSequentially();

Comment prévenir

  • Adoptez des styles de codage asynchrones avec promesses ou async/await.
  • Utilisez l'ESLint rule no-callback-literal pour empêcher les callbacks inutiles.

Erreur 2 : Fuites de Mémoire

Le problème

La fuite de mémoire se produit lorsque des objets sont stockés en mémoire mais ne peuvent plus être accessibles, ce qui entraîne un consommation inutile de ressources.

function createObjects() {
    for (let i = 0; i < 1e6; i++) {
        let obj = { data: new Array(1e6).fill(i) };
        // Do something with obj
    }
}

Pourquoi c'est une erreur

  • Performance : Les fuites de mémoire augmentent le temps d'activité du processus, ce qui peut entraîner des performances dégradées.
  • Sécurité : Les objets inaccessibles peuvent être utilisés par d'autres parties du code, causant des problèmes de sécurité.

La solution

Utilisez les structures de données appropriées et supprimez les références inutiles :

function createObjects() {
    for (let i = 0; i < 1e6; i++) {
        let obj = { data: new Array(1e6).fill(i) };
        // Do something with obj
        obj = null; // Remove reference to free memory
    }
}

Comment prévenir

  • Utilisez des outils comme node-memwatch pour détecter les fuites de mémoire.
  • Adoptez l'ESLint rule no-unused-vars pour identifier les variables inutilisées.

Erreur 3 : Manque d'Error Handling

Le problème

Le manque d'error handling peut entraîner des exceptions non gérées qui arrêtent le processus de manière imprévisible.

function readFile(filePath) {
    const data = fs.readFileSync(filePath, 'utf8');
    console.log(data);
}

Pourquoi c'est une erreur

  • Performance : Les exceptions non gérées peuvent entraîner des performances dégradées.
  • Sécurité : Le manque de protection contre les erreurs peut rendre le code vulnérable à des attaques.
  • Maintenabilité : Des bugs cachés peuvent être difficiles à identifier et à corriger.

La solution

Ajoutez un gestionnaire d'erreurs :

function readFile(filePath) {
    try {
        const data = fs.readFileSync(filePath, 'utf8');
        console.log(data);
    } catch (err) {
        console.error(`Error reading file: ${err.message}`);
    }
}

Comment prévenir

  • Utilisez l'ESLint rule no-empty pour identifier les blocs de code vides.
  • Adoptez la convention d'utiliser des blocks try/catch.

Erreur 4 : Use After Free

Le problème

Le use after free se produit lorsque vous essayez d'accéder à une ressource qui a été libérée.

function readFile(filePath) {
    let data;
    fs.readFile(filePath, 'utf8', function(err, result) {
        if (err) throw err;
        data = result;
    });
    console.log(data); // This will be undefined because the file read is async
}

Pourquoi c'est une erreur

  • Performance : Les accès non autorisés peuvent entraîner des performances dégradées.
  • Sécurité : Le manque de protection contre les erreurs peut rendre le code vulnérable à des attaques.
  • Maintenabilité : Des bugs cachés peuvent être difficiles à identifier et à corriger.

La solution

Utilisez des promesses ou async/await pour gérer les accès asynchrones :

async function readFile(filePath) {
    try {
        const data = await fs.promises.readFile(filePath, 'utf8');
        console.log(data);
    } catch (err) {
        console.error(`Error reading file: ${err.message}`);
    }
}

Comment prévenir

  • Utilisez des outils comme eslint-plugin-security pour détecter les use after free.
  • Adoptez la convention d'utiliser des blocks try/catch.

Erreur 5 : Callbacks Inutiles

Le problème

La création de callbacks inutiles peut entraîner une performance dégradée et rendre le code difficile à lire.

function readFile(filePath, callback) {
    fs.readFile(filePath, 'utf8', function(err, data) {
        if (err) return callback(err);
        callback(null, data);
    });
}

Pourquoi c'est une erreur

  • Performance : Les callbacks inutiles peuvent entraîner des performances dégradées.
  • Sécurité : L'absence de gestionnaire d'erreurs peut rendre le code vulnérable à des attaques.
  • Maintenabilité : Le code est difficile à lire et à modifier, ce qui augmente les risques de bugs.

La solution

Utilisez des promesses ou async/await pour simplifier le code :

async function readFile(filePath) {
    try {
        const data = await fs.promises.readFile(filePath, 'utf8');
        return data;
    } catch (err) {
        throw err;
    }
}

Comment prévenir

  • Utilisez l'ESLint rule no-callback-literal pour empêcher les callbacks inutiles.
  • Adoptez des styles de codage asynchrones avec promesses ou async/await.

Erreur 6 : Manque de Validation des Données

Le problème

Le manque de validation des données peut entraîner des bugs et des attaques potentielles.

function createUser(username, email) {
    if (username && email) {
        // Save user to database
    }
}

Pourquoi c'est une erreur

  • Performance : Les validations inutiles peuvent entraîner des performances dégradées.
  • Sécurité : Le manque de validation peut rendre le code vulnérable aux injections SQL, XSS et autres attaques.
  • Maintenabilité : Des bugs cachés peuvent être difficiles à identifier et à corriger.

La solution

Ajoutez des validations :

function createUser(username, email) {
    if (!username || !email) {
        throw new Error('Username and email are required');
    }
    // Validate username and email format
    const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!regex.test(email)) {
        throw new Error('Invalid email format');
    }
    // Save user to database
}

Comment prévenir

  • Utilisez des outils comme joi pour valider les données.
  • Adoptez la convention d'utiliser des blocks try/catch.

Erreur 7 : Utilisation de Variables Globales

Le problème

L'utilisation excessive de variables globales peut entraîner des conflits et rendre le code difficile à maintenir.

let globalVar = 'I am a global variable';

function doSomething() {
    globalVar = 'I have changed the global variable';
}

doSomething();

Pourquoi c'est une erreur

  • Performance : Les variables globales peuvent entraîner des performances dégradées.
  • Sécurité : Le manque de contrôle sur les variables globales peut rendre le code vulnérable aux attaques.
  • Maintenabilité : Le code est difficile à lire et à modifier, ce qui augmente les risques de bugs.

La solution

Utilisez des variables locales :

function doSomething() {
    let localVar = 'I am a local variable';
    // Use localVar
}

Comment prévenir

  • Utilisez l'ESLint rule no-var pour empêcher l'utilisation de variables globales.
  • Adoptez la convention d'utiliser des variables locales.

Erreur 8 : Manque de Sécurité

Le problème

Le manque de sécurité peut entraîner des vulnérabilités et des attaques potentielles.

app.get('/user/:id', function(req, res) {
    const userId = req.params.id;
    db.query(`SELECT * FROM users WHERE id = ${userId}`, function(err, results) {
        if (err) throw err;
        res.send(results);
    });
});

Pourquoi c'est une erreur

  • Performance : Les validations inutiles peuvent entraîner des performances dégradées.
  • Sécurité : Le manque de validation peut rendre le code vulnérable aux injections SQL, XSS et autres attaques.
  • Maintenabilité : Des bugs cachés peuvent être difficiles à identifier et à corriger.

La solution

Utilisez des paramètres nommés et escape les entrées :

app.get('/user/:id', function(req, res) {
    const userId = req.params.id;
    db.query('SELECT * FROM users WHERE id = ?', [userId], function(err, results) {
        if (err) throw err;
        res.send(results);
    });
});

Comment prévenir

  • Utilisez des outils comme helmet pour ajouter des protections de sécurité.
  • Adoptez la convention d'utiliser des paramètres nommés.

Erreur 9 : Manque de Logging

Le problème

Le manque de logging peut rendre difficile le débogage et la maintenance du code.

function divide(a, b) {
    if (b === 0) throw new Error('Division by zero');
    return a / b;
}

Pourquoi c'est une erreur

  • Performance : Les validations inutiles peuvent entraîner des performances dégradées.
  • Sécurité : Le manque de logging peut rendre difficile la détection et le traitement des erreurs.
  • Maintenabilité : Des bugs cachés peuvent être difficiles à identifier et à corriger.

La solution

Ajoutez des logs :

function divide(a, b) {
    if (b === 0) {
        console.error('Division by zero');
        throw new Error('Division by zero');
    }
    return a / b;
}

Comment prévenir

  • Utilisez un outil de logging comme winston ou pino.
  • Adoptez la convention d'utiliser des logs pour toutes les opérations clés.

Erreur 10 : Manque de Conformité aux Standards

Le problème

Le manque de conformité aux standards peut entraîner des problèmes de compatibilité et des bugs.

const data = JSON.parse(request.body);

Pourquoi c'est une erreur

  • Performance : Les validations inutiles peuvent entraîner des performances dégradées.
  • Sécurité : Le manque de conformité peut rendre le code vulnérable aux attaques.
  • Maintenabilité : Des bugs cachés peuvent être difficiles à identifier et à corriger.

La solution

Utilisez un validateur JSON :

const Ajv = require('ajv');
const ajv = new Ajv();
const schema = {
    type: 'object',
    properties: {
        name: { type: 'string' },
        age: { type: 'number' }
    },
    required: ['name', 'age'],
    additionalProperties: false
};
const validate = ajv.compile(schema);
if (!validate(request.body)) {
    console.error(validate.errors);
    throw new Error('Invalid request body');
}

Comment prévenir

  • Utilisez des outils comme ajv pour valider les données JSON.
  • Adoptez la convention d'utiliser des validateurs standards.

Un projet tech a lancer ?

Besoin d'un accompagnement ? Decrivez votre projet pour des recommandations.

Recevoir des conseils

Questions frequentes

Quelle est la différence entre require() et import() en Node.js ?
En Node.js, require() est utilisé pour importer des modules synchrones tandis que import() permet l'importation de modules de manière asynchrone, introduit avec ECMAScript 2015.
Comment éviter les erreurs liées aux variables globales dans Node.js ?
Pour éviter les erreurs liées aux variables globales, il est recommandé d'utiliser des modules ES6 et de suivre le principe du module par fichier. Cela permet une meilleure organisation du code et réduit la pollution des espaces globaux.
Quelle est la manière correcte de gérer les erreurs asynchrones dans Node.js ?
La gestion des erreurs asynchrones en Node.js peut être effectuée à l'aide de callbacks, de promises ou d'async/await. Il est important de toujours vérifier les erreurs pour éviter des fuites de mémory et des comportements indésirables.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.