fs.rename unable to rename directories with contents on Windows 10 - javascript

So I've seen several questions similar to this issue but I haven't found anything that quite fixes it.
I'm able to rename a directory with node.js as long as the directory is empty. Once I add contents, I get the error: EPERM: operation not permitted. If I delete the contents, I regain the ability to rename. Is there something simple I'm missing here? Nothing crazy in the code... just can't rename a directory if it has contents.
app.post('/rename', function(req, res, next) {
let _target = req.body.target,
_from = req.body.from,
_to = req.body.to;
fs.renameSync(
'public/' + _target + '/' + _from,
'public/' + _target + '/' + _to,
function(err, data) {
if (err) { sLog(err); return }
res.send('File Renamed');
}
);
});
-- EDIT --
The issue is when the directory has sub directories. Files in the directory to rename don't seem to affect the action

The issue is that I was using nodemon instead of node. Apparently, as a listener, it was locking the files... once I ran everything as node, it functioned as expected.

fs.renameSync doesn't work when the folder is not empty, so you should use another way just like the following:
import fsExtra from "fs-extra";
//then copy and delete, disgusting but work
fsExtra.copySync(oldpath, path);
fsExtra.rmdirSync(oldpath, { recursive: true });

Related

How to find tmp folder made by nodejs filesystem?

I was using fs to write values from textarea into a file and had issues with the path until I found on stackoverflow that the path has to be a tmp folder. I did that and the terminal shows the function was successful but now I don't know where that folder is and how I can access.
app.post('/scheduleTweet', function (req, res) {
fs.writeFile('/tmp/scheduleTweet', req.body.text, err => {
if (err) {
console.error(err);
} else{
console.log("success");
}
});
})
Can somebody help me please? I'm self taught so not really sure what to google even.
If the path starts with a /, then fs.writeFile writes to that path on the current drive, for example, to C:/tmp/schedule.txt. Otherwise, it writes relative to the current working directory of the node process. It's easier if you make it relative to the directory containing your Javascript code: fs.writeFile(__dirname + "/tmp/schedule.txt", ...).

why I get ENONET: no such file or directory when the file exists? node.js

I'm doing a crash course on YouTube before I dive deeper into React and NodeJs.
Im trying to check the url from the code and display the right page.
so if the url ends with '/about' I will display the about html.
the problem is that it's not displaying the page.
the file is exist.
it says: ENOENT: no such file or directory.
this is the code:
const server = http.createServer((req,res)=>{
let filePath = path.join(__dirname, 'public', req.url === '/' ? 'index.html' : req.url)
// Checking the extension
let extName = path.extname(filePath)
// Content Type
let contentType = 'text/html'
// check ext and set ceontent type
switch (extName) {
case '.js':
contentType = 'text/javascript'
break
case '.css':
contentType = 'text/css'
break
case '.json':
contentType = 'application/json'
break
case '.png':
contentType = 'image/png'
break
case '.jpg':
contentType = 'image/jpg'
break
}
console.log(contentType, "here")
// Read file
fs.readFile(filePath, (err,content) => {
console.log(filePath)
if (err) {
console.log(err.message)
if (err.code == 'ENONET') {
//Page not found
fs.readFile(path.join(__dirname, 'public', '404.html'), (err,content) => {
res.writeHead(200, {'Content-Type': 'text/html'})
res.end(content, 'utf-8')
})
} else {
// some server error
res.writeHead(500)
res.end(`Server Error ${err.code}`)
}
}else {
// Success
res.writeHead(200, {'Content-Type': contentType})
res.end(content,'utf-8')
}
})
})
//creating the port either getting it from the host, or setting it to 5000
const PORT = process.env.PORT || 5000
// setting the server to listen on the port, and it get's also a call back so i print the server listens
server.listen(PORT, () => console.log(`Server Listening on port ${PORT}`))
I know that the problem is that I miss the extension in the filePath name.
but the thing is that the person I learn from, have the exact same code, and it works for him.
I know that the problem is that I miss the extension in the filePath name. but the thing is that the person I learn from, have the exact same code, and it works for him.
This code could work only if the file about exists in the public directory (with no file extension on it). So, rather than discuss how it worked for someone else, we should discuss how this code can work for you or what you would have to change in it to make it work for you.
Your code expects the path that is passed in the request to be an entire filename in your public directory.
So, when you send a request in for /about, you try to do fs.readFile("about", ...). That's the file that has to exist.
If you want /about to serve a file named /about.html in your file system, then you have check if extName is empty and, if so, add ".html" to the filename to give it a default extension. Or, in some cases, you might check for more than one possibility in the file system. If about isn't found, then check for about.html.
You could add a default .html path by changing this part:
// Checking the extension
let extName = path.extname(filePath);
to this:
// Checking the extension
let extName = path.extname(filePath);
if (!extName) {
extName = ".html";
filePath += ".html";
}
FYI, there's a misspelling too. Change this:
if (err.code == 'ENONET')
to this:
if (err.code == 'ENOENT')
Another word of caution, your server may be vulnerable to some requests putting ../ into the path and then being able to access files outside of your public directory. Most browsers will stop that, but scripted requests could do it.

fs.unlink() does not work and callback does not fire

It was working a while ago, and I'm not sure what changed to where the fs.unlink() function seems to be totally skipped. The file for deletion is saved in the root package directory, while the typescript file that contains my code is in the dist folder. It worked when I passed in only the fileName like this: fs.unlink(fileName). But now that doesn't work, and it also doesn't it work when I explicitly direct it to the root folder by using either fs.unlink("./" + fileName) or fs.unlink("../" + fileName), or even when I hardcode the path!
Below is my code:
s3.putObject(params, function(err, data){
// ...
console.log("Data uploaded to S3 bucket");
fs.unlink("./" + fileName, function(err){
if(err) {
return console.log("Delete error: " + err);
}
else{
console.log("file deleted successfully");
}
});
console.log("Before process.exit()");
process.exit();
});
When run, this code logs:
Data uploaded to S3 bucket
Before process.exit()
So as you can see, it skips both the if and else statements on fs.unlink(), and doesn't delete the file. It's acting like that block of code doesn't exist at all and I can't figure out why.
You are using async unlink function that's why it is executing next statement. Use
unlinkSync instead.

Shebang in Node for windows

I am currently learning Node.JS on my windows machine. I've got my path set up and I've done quite a bit of development already (running all my scripts in cygwin). Finally, it's time for me to run these directly instead of calling 'node --harmony script.js'. The tutorial I'm using says to attach
#!usr/bin/env node --harmony
at the top of the file. Of course, this doesn't exactly work. My path variable says that the node program itself is in:
D:\NodeJS\
I've tried several different ways to use the Shebang to no avail. Every time I run the script, it announces:
./dbcli.js: line 1: #!D:/NodeJS/: no such file or directory
Anyone know how this is supposed to be used? Here's the code so far:
#!d:/NodeJS/node --harmony
const
request = require("request"),
options = {
method: process.argv[2] || 'GET',
url: 'http://localhost:5984/' + (process.argv[3] || '')
};
request(options, function (err, res, body) {
if (err) {
throw Error(err);
} else {
console.log(res.statusCode, JSON.parse(body));
}
});
I found the answer and it turned out to be a bizarre one. Since I was developing in Visual Studio, the files were encoded as UTF-8 With BOM. As a result, it was getting a whole lot of nonsense in the file while attempting to run it directly.
The above code :
#!d:/NodeJS/node --harmony
const
request = require("request"),
options = {
method: process.argv[2] || 'GET',
url: 'http://localhost:5984/' + (process.argv[3] || '')
};
request(options, function (err, res, body) {
if (err) {
throw Error(err);
} else {
console.log(res.statusCode, JSON.parse(body));
}
});
was exactly what I needed, but, since it was incorrectly encoded, it never worked. For the time being, I'm editing all scripts in Visual Studio and, for the ones I want to run directly, I'll open Notepad++ and switch over the encoding (until I find a better way).

node.js / Express throws 'RangeError: Maximum call stack size exceeded' under high load

We are having an issue with our node environment running under high
load that we have not been able to find the source of.
A little background: we are running a clustered node application using
Express for the http framework. Currently, there are 3 boxes with 8
CPU cores on each, and each box is running a cluster of 6 node
workers. The setup seems to work great and I've researched all the
suggested methodologies such that I believe the setup is solid. We're
running node.js 0.8.1 with Express 2.5.11 and XMLHttpRequest 1.4.2.
Here's the issue: We're doing a "dark launch" test of this product
(i.e. the browser client code has javascript ajax calls to our APIs in
the background, but is not used on the page or shown to the user). After a few minutes running successfully, the system is throwing:
[RangeError: Maximum call stack size exceeded]
We're catching the error with the 'uncaughtException' event in the
cluster controller (which starts each worker), however there is no
stack trace available at that level. I've done extensive research on
this issue and can't seem to find anyone with a similar error. After
combing through EVERY line of code in the system, here's what I know:
I cannot find any recursion or circular references. (I've read that
this error doesn't always mean a recursion problem, but we've checked;
we've actually run tests by removing most of the code anyways and it
still happens, see below);
I've gone down to 1 worker process per box to try and eliminate the
cluster as an issue -- the problem still happens;
The problem ONLY happens under high load. Our traffic is approx.
1500 pages per second and, during heavy traffic times, can reach 15000
pages per second (we haven't been able to replicate on a dev
environment);
The timing of the error being caught varies, but is usually within 15 minutes;
The error does NOT seem to impact operation! By this, I mean that
there are no corrupt responses and, aside from the occasional timeout,
the system never crashes;
The worker process that traps the error recovers and starts serving
requests again after a few seconds;
I have gotten the error to happen on the most basic design--no
additional APIs are called. Simply take a request and respond with a
simple json response. This is the most curious part. It doesn't seem
like the system is failing in any of my code -- It's failing without
instantiating any of the classes to do the real work. Obviously, I
started out with more code, but slowly took out pieces until it was
still failing under a bare-bones setup.
The most telling symptom, I believe, is that the error always happens
AFTER a request has been fully served. That is, the server takes a
request, finds the proper Express route, calls res.send, and is
finished. This really feels like garbage collection to me! I've read
that the V8 engine has a very good GC engine, but I'm wondering how
much our heavy load is impacting things.
As I said, the code throws the error even on a basic design. Having
taken out most of our custom code, this is the basics of the setup.
Sorry that I'm cutting here, so not all variable declarations etc will
be included, however the code does work and all that stuff is in the
real code:
Cluster controller. This is a cleaned-up version of what is started on the command line.
cluster = require('cluster');
path = require('path');
fs = require('fs');
app = require('./nodeApi');
_ = require('underscore');
nodeUtil = require(./nodeUtil);
process.on('uncaughtException', function(err) {
var stamp;
stamp = new Date();
console.log("***************************** Exception Caught, " + stamp);
return console.log("Exception is:", err);
});
if (cluster.isMaster) {
if ((nodeUtil.isLiveServer() || nodeUtil.isCluster()) && process.env.IS_CLUSTER !== '0') {
numCPUs = require("os").cpus().length - 2;
if (numCPUs <= 0) {
numCPUs = 1;
}
} else {
numCPUs = 1;
}
console.log("Forking " + numCPUs + " workers...");
for (i = _i = 1; 1 <= numCPUs ? _i <= numCPUs : _i >= numCPUs; i = 1 <= numCPUs ? ++_i : --_i) {
worker = cluster.fork();
}
} else {
app.start();
}
nodeWorker code. Using Express and a simple route to serve a
request. Request is wrapped in a callback if jsonp is used (for our
testing with ajax, this was needed)
(function() {
var crypto, express, fs, modroot, path, staticroot, _;
express = require('express');
_ = require('underscore');
fs = require('fs');
path = require('path');
module.exports.start = function() {
logFile = fs.createWriteStream("" + logpath + "/access.log", {
flags: 'a'
});
app = express.createServer();
app.configure(function() {
app.use(express.logger({
stream: logFile,
format: ':remote-addr - [:date] - ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" :response-time ms'
}));
app.use(express.errorHandler({
dumpExceptions: true,
showStack: true
}));
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.session({
secret: "ourMemStoreSecret",
cookie: {
domain: ".ourdomain.com"
},
maxAge: new Date(Date.now() + 7200000),
// The store WAS a redis store. I took it out to eliminate redis as the issue. We don't use sessions anyway.
store: new require('express').session.MemoryStore({
reapInterval: 60000 * 15
})
}));
app.use(express["static"](staticroot));
app.set('view engine', 'underscore'); // For our template rendering. Not used in this test.
app.set('views', __dirname + '/views/src');
app.set('view options', {
layout: false
});
app.use(app.router);
});
ignore = function(req, res, next) {
if (req.params.api === 'favicon.ico') {
return next('route');
}
return next();
};
wrapCallback = function(req, res, next) {
var callbackName;
if (callbackName = req.query.callback) {
req.wrapCallback = true;
res._send = res.send;
res.send = function(data, status) {
var dataString;
if (_.isObject(data)) {
dataString = encodeURI(JSON.stringify(data));
res.setHeader('Content-Type', 'application/javascript');
return res._send("" + callbackName + "(\"" + dataString + "\")", status);
} else {
data = encodeURI(data);
return res._send("" + callbackName + "(\"" + data + "\")", status);
}
};
}
return next();
};
app.error(function(err, req, res, next) {
console.log("[" + process.pid + "] Error Handler. Ok.", err);
return res.send({
error: err.msg
}, err.statusCode);
});
// Does anyone know how to hard-code a path AND put it into a variable at the same time?
// Kind of like: "/:api=MyTestAPI" ?? That's why this route is here.
setAPIName = function(req, res, next) {
req.params.api = 'MyTestAPI';
return next();
};
app.get("/MyTestAPI", setAPIName, wrapCallback, function(req, res) {
res.send({
hello: 'world'
}, 200);
return console.log("[" + process.pid + "] res.send (no cacher) is done");
});
process.setMaxListeners(0);
process.send({
// For IPC - the controller has a handler for this message
cmd: 'isStarted'
});
return app.listen(process.env.APP_PORT);
};
}).call(this);
What the error looks like. Basically, I never see it happen in
the middle of a request. There isn't a call stack on the error
either--it's only the stack overflow message. Here you can see 2
worker processes each serving a response, then the error on one of
them.
[660] res.send (no cacher) is done
[654] res.send (no cacher) is done
***************************** Exception Caught, Fri Nov 02 2012 10:23:48 GMT-0400 (EDT)
I would really appreciate some feedback on this. The system runs
beautifully and is capable of handling our huge traffic with 3 boxes.
The load on the boxes is about 40% and humming. I'd love to find the
source of this issue so others can be as proud of this system as I am,
and show the node.js non-believers that this is a great product!
I have faced same problem in one of my production environment. During the analysis, I found following things, may be i am wrong. But I hope, this will help you...
This problem is basically associated with Socket. There is a option how many open Socket connection should accept? and can the connection keep in half open?.
Normally this kind of exceptions happen only because of how frequent you hit server in particular time period.
Let me explain clearly...
Let assume there is only two socket path and you have four request each should take 5 seconds of processing time.
In general NodeJs can serve perfectly when you give 2 request in 0th second and remaining 2 in 6th second.
Rather than like this, if you give 4 request in 0th second, then NodeJs ready to serve 2 request only. NodeJs is simply close socket for remaining two request.
Note: Later if you give the same request, NodeJs will accept and give the response.
For more information, please go through socket.io.js implementation.
And my solution is,
Create load balancer in server friendly way.
Run the NodeJs instances or clusters under the load balancer.
Or If you find any other easy way to solve this, Please update this post...
I am waiting to know a great solution for this problem.
Thanks
I thought I would update my own post to explain what the fix was for me.
After realizing that I had done everything else I knew how to do, the solution presented itself by doing this:
Install Express version 3
There were so many differences and changes that needed to be made to the core code that it took me a full day just to do the conversion. However, in doing so, I was able to take advantage of many new v3 featuers including the .param method for attaching helpers to your :param variables in each route. This eliminated several of my old "helper" functions, so instead of chaining through the routes, I used that instead.
I now have a full understanding of routes/middleware, and simply by re-writing for Express v3, my problem went away!
Since this isn't an exact answer, these are the things I used to learn how to make the conversion:
Express v3 API reference
Information on how routes work
Awesome HOWTO doc! Thanks to those guys!

Categories

Resources