Lucifer Morningstar
Lucifer Morningstar

Reputation: 139

error while reading json file using fs in Node js

I am working on a 3 layer architecture backend for node JS and Express.

I have to read a file with JSON data and send using HTTP using REST

My problem is that the error thrown from fs.readFile is not being propogated above to upper layer, despite using throw. However the code works with fs.readFileSync.

dao.js

const fs = require("fs");

class DAO {
    async getAllProducts() {
        // try {
        //  fs.readFileSync("products.json");
        // } catch (error) {
        //  throw new Error("Error Reading File");
        // }
        fs.readFile("./products.json", (err, data) => {
            if (err) {
                throw new Error("Error Reading File");
            } else {
                let d = JSON.parse(data);
                return d;
            }
        });
    }
}

module.exports = new DAO();

service.js

const dao = require("../data/dao");

class Service {
    async getAllProducts() {
        try {
            return await dao.getAllProducts();
        } catch (error) {
            throw error;
        }
    }
}

module.exports = new Service();

product.js

const express = require("express");
const router = express.Router();
const service = require("../service/service");
const Response = require("../models/Response");

router.get("/", async (req, res) => {
    try {
        const data = await service.getAllProducts();
        res.status(200).send(new Response(200, "Success", null, data));
    } catch (error) {
        res.status(500).send(new Response(500, "Failure", error.message, null));
    }
});

module.exports = router;

On hitting http://localhost:3000/api/products and using the fs.readFileSync method, the o/p is as expected

{
    "statusCode": 500,
    "status": "Failure",
    "message": "Error Reading File",
    "data": null
}

but on using fs.readFile the o/p is weird

{
    "statusCode": 200,
    "status": "Success",
    "message": null
}

and the console output is below

                                throw new Error("Error Reading File");
                                ^

Error: Error Reading File
    at ReadFileContext.callback (C:\Users\a\b\c\d\data\dao.js:12:11)
    at FSReqCallback.readFileAfterOpen [as oncomplete] (fs.js:264:13)

my guess is because the readfile is an async fn so it's causing problem but to counter that, I have used async/await everywhere so there should'nt be a problem. Not sure where the error is.

any help is much appreciated

Upvotes: 1

Views: 1732

Answers (1)

eol
eol

Reputation: 24565

That's because the error is thrown in a callback. The error will not be caught from the catch block in your service (check this article which explains this in detail). Instead of using callbacks and the synchronous read-operation you can use fs's promises though:

async getAllProducts() {
     try {        
        const data = await fs.promises.readFile("./products.json");
        return JSON.parse(data);
     } catch (err) {
        console.log(err); // print the orig error but throw your custom error
        throw new Error("Error Reading File");
     }
}

If readFile rejects, the error will now be caught in your service.

One more thing: Exporting an instance from a module is considered bad practice, see this for more information.

Upvotes: 2

Related Questions