How do I ensure a local directory with fs.readdir() - node.js

So I have an express server that upon a GET request, returns a json file.
app.get('/server-generated/pages.json',function(req, res) {
fs.readdir('public/pages',function(err,data){
res.json(data || err);//temp error checking
});
});
it works just fine when I run node app or forever app in its directory but when I run it as a forever service from Ubuntu upstart on startup
exec forever start /home/*****/transfer/app.js
I get this in response
{
"errno": 34,
"code": "ENOENT",
"path": "public/pages"
}
which is directory error if I'm right? the full folder hierarchy goes like this /home/****/transfer/public/pages
How would I write a directory that would work on any computer (windows/ubuntu) running the app locally or from upstart?

you should use the path relative to the directory where the module is:
var path = require('path');
fs.readdir(path.join(__dirname, 'public/pages'), function(err, data) {
res.json(data || err);
});

Related

electron app.getpath('exe') result is not what I expected

I want to start my app automatically on system startup.
I used auto-launch.
var AutoLaunch = require('auto-launch');
var autoLauncher = new AutoLaunch({
name: "App name",
path: app.getPath('exe'),
});
console.log(`app path : ${app.getPath('exe')}`)
//result : C:\Users\USER-PC\project_folder\dist\electron.exe
autoLauncher.isEnabled().then(function(isEnabled) {
if (isEnabled) return;
autoLauncher.enable();
}).catch(function (err) {
throw err;
});
The problem is, I am using electron-builder for building an exe file. And when I build an exe file its name is like : 'app-name 1.0.0.exe'.
So auto launch is not working properly because the option, 'path' is different from the actual exe file's path.
How can I solve this?
I tried to set the app name so app.getPath('exe') can return the actual .exe path. But it did not work.
app.setName('app-name')

heroku node js create folder issue

I have express app which works fine on localhost, but when I deploy it to heroku it doesn't create any folders, although all other functionality works fine
in order to specify the path to the file i use nodejs path and save it to mongoDB
How it looks on Localhost:5000 after uploading file inside project:
MongoDB file path field:
C:\Users\inbec\OneDrive\New folder\Documents\Code\servers\CooperateFront-back\files/60f063de9e95e729f05dfcfb/60f0642b9e95e729f05dfd02/60f064369e95e729f05dfd07/Screenshot_3.png
How it looks with Heroku:
Heroku CLI: heroku run bash -a cooperatefront-back
~/files $ cd 60f063de9e95e729f05dfcfb
bash: cd: 60f063de9e95e729f05dfcfb: No such file or directory
In Browser:
Cannot GET
/app/files/60f063de9e95e729f05dfcfb/60f05fe09d17a600223700d7/60f05fe59d17a600223700db/Screenshot_1.png
MongoDB file path field: /app/files/60f063de9e95e729f05dfcfb/60f05fe09d17a600223700d7/60f05fe59d17a600223700db/Screenshot_1.png
index.js
app.use(filePathMiddleWare(path.resolve(__dirname, "files")))
app.use(fileUpload({}))
app.use("/files",express.static("files"))
filepath-middleware:
function filePath(path) {
return function (req, res, next) {
req.filePath = path
next()
}
}
module.exports = filePath
FileService:
class FileService {
createDor(req,file) {
console.log(req.filePath, "filePath")
const filePath = `${req.filePath}\\${file.user}\\${file.path}`
return new Promise(((resolve, reject) => {
try {
if (!fs.existsSync(file)) {
fs.mkdirSync(filePath)
return resolve({message: "File was created"})
} else {
return reject({message: "File already exists"})
}
} catch (e) {
console.log(e)
return reject({message: "File error"})
}
}))
}
}
Found ussue:
no need to specify the /app folder to get file
{myHerokuSite}/files/60f06d3f41e750002225c04a/60f06d4641e750002225c051/60f06d4c41e750002225c055/photo_2021-02-22_09-33-17.jpg
and just in case changed \\ to /
const filePath = ${req.filePath}\\${file.user}\\${file.path} =>
${req.filePath}/${file.user}/${file.path}
I know you have already answerd your own question here but just be aware that Heroku is essentially a CASS service (container as a service)
This means ephemeral storage is not persistent. Each time you restart, redeploy all items will be lost.
A better approach would be do use an object store like S3. This will allow you to store the images on a persistent volume that will allow your application to keep working even with restarts as the code runs on the container and dynamic / user create assets will be stored in the object store and shared across all running instances.

Node PhantomJS script onResourceError path issue

Having some trouble using the webpage API in a phantomJS script I'm using for load testing.
I'm running the script in a child process, like so:
var path = require('path');
var childProcess = require('child_process');
var binPath = require('phantomjs').path;
var childArgs = [
path.join(__dirname, 'phantom-script.js')
];
var spawn = childProcess.spawn;
var child = spawn(binPath, childArgs);
child.stdout.on('data', function(data) {
const buf = Buffer.from(data);
console.log('stdout:', buf.toString());
});
child.stderr.on('data', function(data) {
const buf = Buffer.from(data);
console.log('stderr:', buf.toString());
});
And my simple phantomJS script:
var webPage = require('webpage');
var page = webPage.create();
page.onConsoleMessage = function (msg) {
console.log(msg);
};
page.onResourceError = function(resourceError) {
console.log(resourceError.errorCode + ':', resourceError.errorString);
};
function runScript() {
page.open('<webpage-url>', function(status) {
console.log('Status:', status);
if (status === 'success') {
page.evaluate(function() {
console.log('Title:', document.title);
});
}
});
}
runScript();
So to start the phantomJS script, if both of these files are in the test/ directory, and my current directory is up one from that: node test/child-process.js, which then spawns the child process and runs my phantomJS script.
So, this gets the script to run, but it always fails in page.open because of a resource error. Replacing my url with Google's, or really any website, works fine.
The error logged in onResourceError is stdout: 202: Cannot open file:///Users/<user>/path/to/local/current/directory: Path is a directory.
This is always the path from which I'm running this script. If I move down a directory into test/ and run it with node child-process.js, the error instead logs that directory.
As a headless browser, I assumed phantomJS would interface with a webpage like any client would, just without rendering the template--what does the current directory from which the script was run have anything to do with opening the webpage? Why would it be trying to load resources from my local directory when the webpage URL points to a public website, hosted at the IP and PORT specified in the first argument of page.open (e.g. xx.xxx.xx.xx:PORT)?
I'm at a bit of a loss here. The phantomJS path and all that is correct, since it runs the script fine. I just don't understand why page.open would attempt to open the directory from which the script was called--what does that have to do with its function, which is to open the URL and load it to the page?
Not sure if this is even worthy of answering--as opposed to just deleting.
I figured it out when I manually typed in the argument www.google.com, instead of copy/pasting from the browser, and and I got this as the path in the error: file:///Users/<user>/path/to/local/current/directory/www.google.com.
Now I know why I couldn't find a SO question for it. A stupid error on my part at any rate, it would've been a quick debug if the error had appended the IP address and PORT (my "url") to the end of the file path like it did for www.google.com, a clear indicator that it's not pinging a URL.
TL;DR: It's a URL, you need http(s)://...

Node.JS windows service cannot start

I'm using windows-service package to run my script as a windows service.
if (process.argv[2] == "--add") {
logger.info('Starting to add service', global.appRoot + "\\app.js")
ws.add (config.service_name, {programPath: global.appRoot + "\\app.js"});
logger.info('Service added', config.service_name, global.appRoot + "\\app.js")
} else if (process.argv[2] == "--remove") {
logger.info('Removing service', config.service_name)
ws.remove (config.service_name);
logger.info('Service removed', config.service_name)
} else if (process.argv[2] == "--run") {
logger.info('Starting service', config.service_name);
ws.run (logger, function() {
logger.info('Stopping service', config.service_name);
ws.stop()
logger.info('Service stopped')
});
} else if (process.argv[2] == "--stop") {
logger.info('Stopping service', config.service_name);
ws.stop()
logger.info('Service stopped')
}
After running "node service.js --add", I have verified that my windows service is installed correctly with command like below
"C:\Program Files\nodejs\node.exe" "E:\Utils\app.js"
I pasted the command into node.js command prompt and it launched the script correctly.
However, when I tried to start the windows service from the service console, it always complains
Error 1053: The service did not respond to the start or control request in a timely fashiion.
I tried "node service.js --run", it simply prints out the "Starting service" message and hangs there. The underlying script isn't kicked off either.
Verified service log, no error. No script-specific log is generated.
All my script objects are using global.appPath for absolute path reference.
I run out of ideas. Any advice on this matter?

Unable to read a saved file in heroku

I am using NodeJS on heroku.
I read a file from another server and save it into my application in the /temp directory.
Next, I read the same file to pass it on to my client.
The code that saves the file and then subsequently reads it is:
http.request(options, function (pdfResponse) {
var filename = Math.random().toString(36).slice(2) + '.pdf',
filepath = nodePath.join(process.cwd(),'temp/' + filename);
pdfResponse.on('end', function () {
fs.readFile(filepath, function (err, contents) {
//Stuff to do after reading
});
});
//Read the response and save it directly into a file
pdfResponse.pipe(fs.createWriteStream(filepath));
});
This works well on my localhost.
However, when deployed to heroku, I get the following error:
events.js:72
throw er; // Unhandled 'error' event
Error: ENOENT, open '/app/temp/nvks0626yjf0qkt9.pdf'
Process exited with status 8
State changed from up to crashed
I am using process.cwd() to ensure that the path is correctly used. But even then it did not help. As per the heroku documentation, I am free to create files in the applications directory, which I am doing. But I can't figure out why this is failing to read the file...
The error you describe there is consistent with /app/temp/ not existing. You need to create it before you start writing in it. The idea is:
var fs = require("fs");
var path = require("path");
var temp_dir = path.join(process.cwd(), 'temp/');
if (!fs.existsSync(temp_dir))
fs.mkdirSync(temp_dir);
I've used the sync version of the calls for illustrations purposes only. This code should be part of the start up code for your app (instead of being called for each request) and how you should structure it depends on your specific application.

Resources