Reputation: 139
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
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