I'm getting a problem while running the test cases using the node.js application where I'm creating a directory if not exists, writing the json and reading the file.
Here's the Working Demo Link
It's throwing the below error even after handling the error in the code. I didn't get much help from other solutions related to Promise rejection in Stackoverflow. Looking for a working solution. I'm getting the below issue after doing npm test
:
should reject with an error if the passed data is invalid:
Uncaught TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of Promise
at TypeError.get (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:385021)
at EventEmitter.emit (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:143926)
at process.onGlobalUncaughtException [as _fatalException] (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:363886)
at triggerUncaughtException (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:42:367400)
at processPromiseRejections (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:1794051)
at processTicksAndRejections (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:801887)
at _0x263935 (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:37:263515)
While doing npm start
I'm getting the below problem:
Server running at http://127.0.0.1:3000/
Error: Invalid data
at writeJSON (file:///home/projects/stackblitz-starters-xzxhal/index.js:70:15)
at Server.eval (file:///home/projects/stackblitz-starters-xzxhal/index.js:24:15)
TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of Promise
at TypeError.get (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:385021)
at triggerUncaughtException (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:42:367449)
at processPromiseRejections (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:1794051)
at processTicksAndRejections (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:801887)
at _0x263935 (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:37:263515) {
code: 'ERR_INVALID_ARG_TYPE'
}
Here's my index.js
file code pieces:
const server = http.createServer(async (req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
const dirPath = DIR_PATH + dirs[0];
const filePath = dirPath + './data.json';
let createdDirectoryIfNotExists = await createDirectoryIfNotExists(filePath);
if (createdDirectoryIfNotExists) {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.write(writeJSON('./temp', contents));
res.end();
}
});
// write json in file
const writeJSON = async (filePath, contents) => {
try {
if (contents && typeof contents === "object") {
const jsonString = JSON.stringify(contents);
// write file
let isWriteFileSynced = fs.writeFileSync(filePath, jsonString, error => {
if (error) {
console.log(error);
} else {
return jsonString;
}
})
if (isWriteFileSynced) {
// read file after file is written
let isReadFileSynced = fs.readFileSync(filePath, "utf8", (error, jsonString) => {
if (error) {
return false;
} else {
return jsonString;
}
})
// if read file, return the jsonString
if (isReadFileSynced) {
return jsonString;
}
} else {
throw new Error("Invalid data");
}
return jsonString;
}
} catch (error) {
console.log(error);
return;
}
};
// create directory if not exists
const createDirectoryIfNotExists = async (path) => {
fs.mkdirSync(path, { recursive: true });
return true;
};
How to solve this issue?
That error comes from writeJSON
, which returns unresolved Promise, hence the error
So, you need to await it:
res.write(await writeJSON('./temp', contents));
But, as pointed out in the comments, you use sync methods within the function, so no need to return a Promise, so no need to use async
on writeJSON
function
Also, fs.writeFileSync
does not take a callback, and it returns undefined
, so the check part will always fail.
It throws, so you need to wrap both fs
methods in try/catch
, and return json from the try
part.
Also, not sure why you read the file afterwards, if it didn't throw, it's written but you can reorganize that:
Here's a starter that should work (somewhat):
const writeJSON = (filePath, contents) => {
try {
if (contents && typeof contents === 'object') {
const jsonString = JSON.stringify(contents);
// write file
try {
fs.writeFileSync(
filePath,
jsonString
);
// read file after file is written
let isReadFileSynced = fs.readFileSync(
filePath,
'utf8'
);
// if read file, return the jsonString
if (isReadFileSynced) {
return jsonString;
}
} catch (err) {
console.log(err);
}
} else {
throw new Error('Invalid data');
}
} catch (error) {
console.log(error);
return;
}
};
edit
tests passing function:
const writeJSON = async (filePath, contents) => {
if (contents && typeof contents === 'object') {
const jsonString = JSON.stringify(contents);
// write file
try {
fs.writeFileSync(filePath, jsonString);
// read file after file is written
let isReadFileSynced = fs.readFileSync(filePath, 'utf8');
// if read file, return the jsonString
if (isReadFileSynced) {
return jsonString;
}
} catch (err) {
console.log(err);
// todo
throw new Error('err writing');
}
} else {
throw new Error('Invalid Data');
}
};