Having an issue where I will randomly get this error after about an hour of my code running.
SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
Here is my code:
function matchMaking() {
setInterval(function() {
fs.readFile('./rankedQueue.json', 'utf8', function(err, data) {
const file = JSON.parse(data); //The line the error occurs
if (err) {
console.log(err)
} else {
//lots of code here
}
})
}, 10 * 1000)
}
edit: This is the content of the JSON file.
{
"queue": [],
"waiting": [],
"lowLevel": [],
"placeHolder": [
{
"test": "test"
}
]
}
The arrays are being pushed to, and then spliced a couple times a minute.
After searching here and some forums, I've tried using fs.readFileSync, which makes the code not run at all. And now I'm finding some specific examples of this error that I can't quite seem to make the solutions apply to me. If anyone has any idea of what I should be changing, It would be appreciated.
Thanks in advance.
As the errors said data is not in json type
Can you make sure the file is valid and it's is what JSON.parse() can parse
How to use fs.readFileSync
Using fs.readFileSync returns a buffer. You can easily convert the buffer into something readable. You use buffer.toString('ascii'). Also, fs.readFile has a callback argument while readFileSync DOESN'T. What I think you were doing about readFileSync was:
fs.readFileSync('./rankedQueue.json', 'utf8', function(err, data) {
const file = JSON.parse(data); //The line the error occurs
if (err) {
console.log(err)
} else {
//lots of code here
}
})
But you should actually be doing this:
var data = fs.readFileSync('./rankedQueue.json');
var JSON = JSON.parse(data.toString('ascii'));
You could drop the 'ascii'.
Incorrect / Hacky Answer
Use require instead. Node.JS has it so it can parse a JSON file for you. Keep in mind that the way you require a file compared to fs is different.
If your code is located at /project/foobar/code.js
JSON is at /project/rankedQueue.json
fs automatically goes to the top of where your project folder is, e.g. /project & So ./rankedQueue.json
require does not do this, and stays in the folder where the file is. You have to add ../ for every folder you want to go above. So: ./../rankedQueue.json.
I'd suggest also running your JSON through a validator as well so it can tell you whats wrong.
I have a file(data.file an image), I would like to save this image. Now an image with the same name could exist before it. I would like to overwrite if so or create it if it does not exist since before. I read that the flag "w" should do this.
Code:
fs.writeFile('/avatar/myFile.png', data.file, {
flag: "w"
}, function(err) {
if (err) {
return console.log(err);
}
console.log("The file was saved!");
});
Error:
[Error: ENOENT: no such file or directory, open '/avatar/myFile.png']
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: '/avatar/myFile.png'
This is probably because you are trying to write to root of file system instead of your app directory '/avatar/myFile.png' -> __dirname + '/avatar/myFile.png' should do the trick, also check if folder exists. node.js won't create parent folder for you.
Many of us are getting this error because parent path does not exist. E.g. you have /tmp directory available but there is no folder "foo" and you are writing to /tmp/foo/bar.txt.
To solve this, you can use mkdirp - adapted from How to write file if parent folder doesn't exist?
Option A) Using Callbacks
const mkdirp = require('mkdirp');
const fs = require('fs');
const getDirName = require('path').dirname;
function writeFile(path, contents, cb) {
mkdirp(getDirName(path), function (err) {
if (err) return cb(err);
fs.writeFile(path, contents, cb);
});
}
Option B) Using Async/Await
Or if you have an environment where you can use async/await:
const mkdirp = require('mkdirp');
const fs = require('fs');
const writeFile = async (path, content) => {
await mkdirp(path);
fs.writeFileSync(path, content);
}
I solved a similar problem where I was trying to create a file with a name that contained characters that are not allowed. Watch out for that as well because it gives the same error message.
I ran into this error when creating some nested folders asynchronously right before creating the files. The destination folders wouldn't always be created before promises to write the files started. I solved this by using mkdirSync instead of 'mkdir' in order to create the folders synchronously.
try {
fs.mkdirSync(DestinationFolder, { recursive: true } );
} catch (e) {
console.log('Cannot create folder ', e);
}
fs.writeFile(path.join(DestinationFolder, fileName), 'File Content Here', (err) => {
if (err) throw err;
});
Actually, the error message for the file names that are not allowed in Linux/ Unix system comes up with the same error which is extremely confusing. Please check the file name if it has any of the reserved characters. These are the reserved /, >, <, |, :, & characters for Linux / Unix system. For a good read follow this link.
It tells you that the avatar folder does not exist.
Before writing a file into this folder, you need to check that a directory called "avatar" exists and if it doesn't, create it:
if (!fs.existsSync('/avatar')) {
fs.mkdirSync('/avatar', { recursive: true});
}
you can use './' as a prefix for your path.
in your example, you will write:
fs.writeFile('./avatar/myFile.png', data.file, (err) => {
if (err) {
return console.log(err);
}
console.log("The file was saved!");
});
I had this error because I tried to run:
fs.writeFile(file)
fs.unlink(file)
...lots of code... probably not async issue...
fs.writeFile(file)
in the same script. The exception occurred on the second writeFile call. Removing the first two calls solved the problem.
In my case, I use async fs.mkdir() and then, without waiting for this task to complete, I tried to create a file fs.writeFile()...
As SergeS mentioned, using / attempts to write in your system root folder, but instead of using __dirname, which points to the path of the file where writeFile is invoked, you can use process.cwd() to point to the project's directory. Example:
writeFile(`${process.cwd()}/pictures/myFile.png`, data, (err) => {...});
If you want to avoid string concatenations/interpolations, you may also use path.join(process.cwd(), 'pictures', 'myFile.png') (more details, including directory creation, in this digitalocean article).
I've got the following code:
fs.open("uploads/test.txt", "a", "0755", function(err, fd){
if(err) { console.log(err); }
else {
file.handler = fd; //We store the file handler so we can write to it later
...
}
});
The file is created and written to perfectly when I simply have "uploads/test", but when I try to do "uploads/test.txt" it breaks. Any ideas?
I think you should try using
var path = './uploads/test.txt'.
Or
var path = __dirname + 'your_path';
fs.open(path, "a", "0755", function(err, fd){
if(err) { console.log(err); }
else {
file.handler = fd; //We store the file handler so we can write to it later
...
}
});
This is really silly, but I found what was causing my code to break:
fs.open works as intended. The bug was with my file detection setup using nodemon.
The reason is everytime my app would load it would run the above mentioned code. The code would then write to a new file in my apps /uploads directory. Nodemon would then detect the new file and restart the app thus creating a vicious circle.
I'm using http.request to download JPEG file. I am then using fs.writeFile to try to write the JPEG file out to the hard drive.
None of my JPEG files can be opened, they all show an error (but they do have a file size). I have tried all of the different encodings with fs.writeFile.
What am I messing up in this process?
Here's what the working one is showing when viewing it raw:
And here is what the bad one using fs.writeFile is showing:
Figured it out, needed to use res.setEncoding('binary'); on my http.request.
Thank you, looking to the previous response, I was able to save de media correctly:
fs.writeFile(
filepath + fileName + extension,
mediaReceived, // to use with writeFile
{ encoding: "binary" }, // to use with writeFile ***************WORKING
(err) => {
if (err) {
console.log("An error ocurred while writing the media file.");
return console.log(err);
}
}
);
I am trying to save project and its file in GridFS. I want to save project first and using "_id" of project as metadata for file I want to save file. When i tried so i am getting ENOENT, open '/tmp/45e85388793de' error. here is my code
newProject.save(function (err,project) {
if (err) {
console.log('save error', err);
}
console.log("project added");
var id=poject._id;
var filepath = req.files.file.path;
var filename = req.files.file.name;
var writestream = gfs.createWriteStream({ filename: filename, metadata:id });
console.log(filepath);
fs.createReadStream(filepath)
.on('end', function() {
})
.on('error', function(err) {
console.log("error encountered"+err);//ENOENT,open error
})
.pipe(writestream);
});
Why i am getting this error and how to resolve it?
ENOENT in this context means "No such file or directory." It means the filepath you are trying to read with createReadStream does not exist.
I think you are getting this error since :
Your file is saved in a temporary location.
When you are inside the callback function your file is removed from that location and you are getting "No such file" error. Path and other variables still exists as part of js and that's why you are able to print them in console.
Solution:
Above(Outside) callback function move your file to some other permanent location using:
fs.rename(req.files.file.path, "./someKnownPath/filename");
Keep note of that location. In your callback function use the new location as path and try saving the file in gridfs. Once the file is saved you may delete it file from that location(/someKnownPath/filename).
This error was occuring for me as well. And the reason was temp directory was not in place. After I created manually and gave a try, it worked.
Now I have shifted to creating directory on the fly through node.js itself.