I'm trying to delete a folder recursively but the folder itself is still there (empty) when using fs.rmdir(dest, { recursive: true });
Has anyone else come across this issue and if so how did you manage to fix it?
I'm using Node v14.17.0
A hacky solution to anyone else having the same issue:
fs.rmdir(dest, { recursive: true }, (err) => {
if (err) throw err;
try {
if (fs.existsSync(dest)) fs.unlinkSync(dest);
} catch (e) {
// handle error
return;
}
});
im trying to scrape some website , i use a service to bypass captcha using their library
here simplified version of my code
const dbc = require('./deathbycaptcha.js');
open_tab();
async function open_tab()
{
try {
const captcha = await solvecaptcha('xxxx' ,'somedomain' ) .catch(function (error) {throw new Error('caperror'); });
console.log('captcha is solved !');
}
catch(e)
{
console.log('--------ERRRO--------------------------');
console.log(e.message);
}
}
function solvecaptcha(datakey , url )
{
return new Promise(function(resoulve, reject){
const client = new dbc.HttpClient(config.captcha.username, config.captcha.password);
try
{
client.decode({extra: {type: 4, token_params: some_params}}, (captcha) => {
if (captcha) {
resoulve(captcha['text']);
else
reject('cant solve captcha!');
});
}
catch (e) {
reject('cant solve captcha!');
}
});
}
so it starts in the open_Tab function , i call solvecaptcha there and it returnes the solved captcha and its all good ... but sometimes there is a connection error in deathbycaptcha.js which will break the whole code
like if i close my internet connection and try this i get this error and the program crashes
C:\wamp64\www\domain_check\robot\DBC\deathbycaptcha.js:208
throw new Error(err.message);
^
Error: getaddrinfo ENOTFOUND api.dbcapi.me api.dbcapi.me:80
at ClientRequest.form.submit (C:\wamp64\www\domain_check\robot\DBC\deathbycaptcha.js:208:15)
at ClientRequest.emit (events.js:189:13)
at Socket.socketErrorListener (_http_client.js:392:9)
at Socket.emit (events.js:189:13)
at emitErrorNT (internal/streams/destroy.js:82:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
at process._tickCallback (internal/process/next_tick.js:63:19)
i like to be able to control this exception so it wouldn't break the whole code , but no matter how many try/catch i use to control this ... ti wouldn't work and still breaks my code
and its this line that cuzes the problem
client.decode({extra: {type: 4, token_params: some_params}}, (captcha) => {
if (captcha) {
resoulve(captcha['text']);
else
reject('cant solve captcha!');
});
even though i've wrapped it inside try/catch its no use !
I'm mapping an index.html file to scrape the tag content and save as a file called fonts.css
This is my style:
<style>#font-face{font-family:Averti;src:url(https://services.serving-sys.com/HostingServices/custdev/site-140253/Averti/Averti-Bold.woff) format('truetype');font-weight:700;font-style:normal}#font-face{font-family:Averti-Light;src:url(https://services.serving-sys.com/HostingServices/custdev/site-140253/Averti_Webfonts/Averti-Light.woff) format('truetype');font-weight:400;font-style:normal}</style>
There is no major errors with the function, but the console.log is showing me that
{ [Error: ENOENT: no such file or directory, open './dist/css/fonts.css']
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: './dist/css/fonts.css' }
I'm not sure if that is right as the file is not even created yet.
See my function below and let me know what I am missing.
Thank you in advance.
async function createStyle(){
var jsonObject = []
setTimeout(function(){
fs.readFile('./dist/index.html', 'utf8', function(err, html){
if (!err){
const $ = cheerio.load(html)
var cssScript = $('head > style').map(( i, x ) => x.children[0])
.filter(( i, x ) => x && x.data.match(/#font-face/)).get(0);
jsonObject.push(cssScript)
exportStyle(jsonObject)
}
})}, 2000);
async function exportStyle(_json) {
const stylePromise = new Promise(function(resolve, reject) {
fs.writeFile('./dist/css/fonts.css', _json, err => {
if (err) {
reject();
} else {
resolve();
console.log('Created: fonts.css');
}
console.log(err);
});
});
(async function() {
try {
await stylePromise;
} catch(err) {
console.log(err);
}
})();}}
I created the css and js folder inside the ./dist folder and the code worked like a charm. Other than that, the error message appears in the console.
I have this fragment of code in a promise:
try {
const newFile = fs.createWriteStream(filePath);
response.pipe(newFile);
newFile.on('finish', () => {
newFile.close(resolve());
});
} catch (err) {
reject(err);
}
response is the result from get method in the http module, and
filePath is a string /a/b/c/file.mp3/ where the folder /a/b/c does not exist.
Instead of the error being caught, the next line after this fragment is executed and it then crashes with:
ENOENT: no such file or directory, open '/a/b/c/file.mp3' at WriteStream.onerror ... at WriteStream.emit ... at lazyFs.open ... at FSReqWrap.oncomplete
Why is it behaving in this way?
The code works fine if filePath is a valid path.
WritableStream is asynchronous, and you can't catch its errors using try...catch. You should listen for an error event.
const newFile = fs.createWriteStream(filePath);
response.pipe(newFile);
newFile.on('finish', () => {
newFile.close(resolve());
});
newFile.on('error', reject);
or more verbosely
newFile.on('error', exception => {
reject(exception);
});
Hej There,
I'm trying to add some non-conventional functionality to my NodeJS application but I'm having some trouble.
What I'm trying to do is the following:
I want to update my server code from the client. (An auto-update functionality if you will.)
My first attempt was to utilize the NPM API and run:
npm.commands.install([package], function(err, data)
But of course this results in an error telling me NPM can not install while the server is running.
My second attempt was spawning NPM update using the following code:
spawnProcess('npm', ['update'], { cwd: projectPath }, done);
The spawnProcess function is a generic spawn function:
var projectPath = path.resolve(process.cwd());
var spawnProcess = function(command, args, options, callback) {
var spawn = require('child_process').spawn;
var process = spawn(command, args, options);
var err = false;
process.stdout.on('data', function(data) {
console.log('stdout', data.toString());
});
process.stderr.on('data', function(data) {
err = true;
console.log('stderr', data.toString());
});
if (typeof callback === 'function') {
process.on('exit', function() {
if (!err) {
return callback();
}
});
}
};
But this gives me a stderr followed by a 'CreateProcessW: can not find file' error.
I don't quite know what I'm doing wrong.
If all else fails I thought it might be possible to write a shellscript killing Node, updating the application and then rebooting it. Something like:
kill -9 45728
npm update
node server
But I don't know if this is a plausible solution and how I would go about executing it from my node server.
I'd rather have the spawn function working of course.
Any help is welcome.
Thanks in advance!
So I finally fixed this issue. If someone is interested how I did it, this is how:
I built a function using the NPM api to check if the current version is up to date:
exports.checkVersion = function(req, res) {
npm.load([], function (err, npm) {
npm.commands.search(["mediacenterjs"], function(err, data){
if (err){
console.log('NPM search error ' + err);
return;
} else{
var currentInfo = checkCurrentVersion();
for (var key in data) {
var obj = data[key];
if(obj.name === 'mediacenterjs' && obj.version > currentInfo.version){
var message = 'New version '+obj.version+' Available';
res.json(message);
}
}
}
});
});
}
var checkCurrentVersion = function(){
var info = {};
var data = fs.readFileSync('./package.json' , 'utf8');
try{
info = JSON.parse(data);
}catch(e){
console.log('JSON Parse Error', e);
}
return info;
};
If the version is not up to date I initiate a download (in my case the github master repo url) using node-wget:
var wget = require('wget');
var download = wget.download(src, output, options);
download.on('error', function(err) {
console.log('Error', err);
callback(output);
});
download.on('end', function(output) {
console.log(output);
callback(output);
});
download.on('progress', function(progress) {
console.log(progress * 100);
});
The callback kicks off the unzip function bases on #John Munsch 'Self help' script but I added a check to see if there was a previous unzip attempt and if so, I delete the folder:
if(fs.existsSync(dir) === false){
fs.mkdirSync(dir);
} else {
rimraf(dir, function (err) {
if(err) {
console.log('Error removing temp folder', err);
} else {
fileHandler.downloadFile(src, output, options, function(output){
console.log('Done', output);
unzip(req, res, output, dir);
});
}
});
}
console.log("Unzipping New Version...");
var AdmZip = require("adm-zip");
var zip = new AdmZip(output);
zip.extractAllTo(dir, true);
fs.openSync('./configuration/update.js', 'w');
The openSync function kicks off my 'NodeMon' based file (https://github.com/jansmolders86/mediacenterjs/blob/master/server.js) which kills the server because it is listing for changes to that specific file. Finally it restart and starts the following functions:
function installUpdate(output, dir){
console.log('Installing update...');
var fsExtra = require("fs.extra");
fsExtra.copy(dir+'/mediacenterjs-master', './', function (err) {
if (err) {
console.error('Error', err);
} else {
console.log("success!");
cleanUp(output, dir);
}
});
}
function cleanUp(output, dir) {
console.log('Cleanup...');
var rimraf = require('rimraf');
rimraf(dir, function (e) {
if(e) {
console.log('Error removing module', e .red);
}
});
if(fs.existsSync(output) === true){
fs.unlinkSync(output);
console.log('Done, restarting server...')
server.start();
}
}
Thanks to everyone that helped me out!
Untested!
Have you tried the "prestart" npm script handle? Of course this would mean that you'd use npm to run your server: npm start
In your package.json (if you have) :
{ "scripts" :
{
"start" : "node server.js",
"prestart" : "scripts/customScript.js"
}
}
NPM start command is implicitly defaulted to "start": "node server.js". If your server script is called server.js, there is no need to include this. You can do your npm install on the customScript.js or might be able to call npm install directly though I haven't tested this.
You can also assign/read your handler using the environment variable process.env.npm_package_scripts_prestart
It doesn't use NPM to accomplish it but here's a working experiment I put together a while back because I wanted to be able to build a self-updating app using Node.js for installation on people's machines (think apps like SABnzbd+, Couch Potato, or the Plex Media Server).
The Github for the example code is here: https://github.com/JohnMunsch/selfhelp
I got the example to the point where it would automatically notify you when a new version was available and then download, update, and restart itself. Even if you don't end up using it as-is, you should be able to get some ideas from it.