I am trying to build and run an executable in Gulp using Node. My executable builds fine, however attempting to run it gives this error:
Error: spawn EACCES
at exports._errnoException (util.js:1023:11)
at ChildProcess.spawn (internal/child_process.js:313:11)
at Object.exports.spawn (child_process.js:387:9)
at Gulp. (/path/to/my/app/gulpfile.js:167:24)
at module.exports (/path/to/my/app/node_modules/orchestrator/lib/runTask.js:34:7)
at Gulp.Orchestrator._runTask (/path/to/my/app/node_modules/orchestrator/index.js:273:3)
at Gulp.Orchestrator._runStep (/path/to/my/app/node_modules/orchestrator/index.js:214:10)
at Gulp.Orchestrator.start (/path/to/my/app/node_modules/orchestrator/index.js:134:8)
at Gulp. (/path/to/my/app/node_modules/gulp-sync/lib/index.js:51:27)
at module.exports (/path/to/my/app/node_modules/orchestrator/lib/runTask.js:34:7)
Bear in mind that my script works perfectly fine when my gulpfile.js is in the same directory as the executable I am attempting to run.
But I have moved my gulpfile.js to one directory down, and in order to build/run the executable I have to change the cwd of the child process I am spawning to the directory above it. In doing so, even though the executable still builds fine, the running of it keeps giving me this error and I can't find any help online.
I tried to set executable permissions on the file, thinking it was a permissions problem, but that didn't do anything.
I also tried putting the logic to run the executable in a shell script and run the shell script using the child process instead (cause why not), but that didn't help either.
Here's the code:
// Spawn application server
if (os.platform() === 'win32') {
// server = child.spawn(appName + '.exe') <-- USED TO WORK
server = child.spawn(appName + '.exe', [], {
cwd: mainDotGoPath
});
} else {
// server = child.spawn('./' + appName) <-- USED TO WORK
server = child.spawn('./' + appName, [], {
cwd: mainDotGoPath
});
}
The path is fine, by the way, because I build the executable using a similar syntax and it builds just fine:
var build = child.spawnSync('go', ['build'], {
cwd: mainDotGoPath
});
Anyone have any ideas?
Related
I am trying to import images I have stored in a folder called resources located under the server section.
When I place the images in the app folder on my local drive, it works fine, but since this has to be deployed to our live server, it makes things hard to have to copy files back and forth.
The error I get:
Error: ENOENT: no such file or directory, open '../../resources/cp_pdf_logo.png'
at Object.openSync (node:fs:585:3)
at Object.readFileSync (node:fs:453:35)
at RouteEmails.orderAuth (C:\Development\kaizen\server\routes\emails\file:\C:\Development\kaizen\server\routes\emails\func.js:187:43)
at RouteEmails.sendMail (C:\Development\kaizen\server\routes\emails\file:\C:\Development\kaizen\server\routes\emails\func.js:430:17)
at RouteOrders.orderAuthorizedMail (C:\Development\kaizen\server\routes\orders\file:\C:\Development\kaizen\server\routes\orders\func.js:840:24)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at RequestRouter._routeRequest (C:\Development\kaizen\server\socketController\file:\C:\Development\kaizen\server\socketController\requestRouter.ts:64:34)
at RequestRouter.processMessage (C:\Development\kaizen\server\socketController\file:\C:\Development\kaizen\server\socketController\requestRouter.ts:43:9)
at Socket. (C:\Development\kaizen\server\socketController\file:\C:\Development\kaizen\server\socketController\socketClient.ts:62:7) {
errno: -4058,
syscall: 'open',
code: 'ENOENT',
path: '../../resources/cp_pdf_logo.png'
}
Here is an example of my code:
let ordercplogo = this.base64_encode("../../resources/cp_pdf_logo.png")
let orderthankyoulogo = this.base64_encode("../../resources/thankyou_logo.png")
// let ordercplogo = this.base64_encode("/app/resources/cp_pdf_logo.png");
// let orderthankyoulogo = this.base64_encode("/app/resources/thankyou_logo.png");
The commented-out section is what works, but from the image below you can see that I have these files stored inside the app.
Can anyone tell me what I'm doing wrong?
PS. I have also tried to import the images above with
const logo1 = require("../../resources/image.png")
but also doesn't work and throws another error.
Your function probably tries to find the image relative to the working directory. It makes a difference if you were to do cd /; node /app/index.js or cd /app; node index.js. The working directory may be different in your live environment than locally.
There are a number of functions to help you find the path to a file in the built-in path module.
Let's assume you're in a file called routes/companies/a.js:
const { resolve } = require('path');
this.base64_encode(resolve(__dirname, "../../resources/cp_pdf_logo.png"));
// Will find the absolute path to the file.
( path.relative documentation page )
In CommonJS files (files that use require()) the value __filename always refers to the file it's in, rather than the main script file (so /app/routes/companies.a.js in this example) and __dirname is the directory it's in. That's the same value, without the a.js part.
In case the lenght of the question might be scary, the summary of the question is how to interact with a front end app from a node server. Puppeteer usage should come along with that request solved I believe. Question is large because I explained all my failed attempts to achieve backend code (puppeteer) work in the browser. Apart from building and running the repo that although its easy right following the instructions might take a some time, I believe the question should be feasable for a javascript/node regular programmer. There it goes, thanks for reading.
I cloned, built and ran imgui-js repository succesfully.
I want to use it along with puppeteer for a small app. All the npm commands inside and stuff tried are inside the mentioned imgui-js project.
I tried:
1.- Run the node example from the project: With npm run-script start-example-node.
This runs the example/index.js script, but nothing is drawn as we are not in the browser and the window is undefined. Can be checked debugging in the main.ts:
if (typeof(window) !== "undefined") {
window.requestAnimationFrame(done ? _done : _loop);
}
So I do not understand the purpose of this example in the repo.
Edit: Seems it can be to have the client-server comunication done, but I do not now how to do this.
2.- Puppeteer browserify:
I followed the browserify hello world.
Just a summary of the steps:
npm install -g browserify
npm i puppeteer
Go to the build folder to generate de bundle.js for my const puppeteer = require('puppeteer'); script, so cd example, cd build, browserify myScript.js -o bundle.js
Add <script src="./build/bundle.js"></script> to the example/index.html.
I obtain this error:
Uncaught TypeError: System.register is not a function
at Object.96.puppeteer (bundle.js:19470:8)
at o (bundle.js:1:265)
at r (bundle.js:1:431)
at bundle.js:1:460
I also tried browserifying main.js along with my script: browserify main.js myScript.js -o bundle.js. Same error.
3.- Try to setup puppeter with the rollup module bundler: following this resource among others. So doing:
npm install --save-dev rollup tape-modern puppeteer
npm install --save-dev rollup-plugin-node-resolve
npm install --save-dev rollup-plugin-commonjs
npm install --save-dev sirv tape-browser-color
And tried to add that the the imgui-js rollup.config.js configuration file.
Think its not working because all the server setup at the npm start and so on is not performed with rollup.
4.- Puppeteer-web: Following the steps of this resource I tried to run puppeteer in the browser.
npm i puppeteer-web
Code in the client and the server:
Client:
<script src="https://unpkg.com/puppeteer-web"></script>
<script>
const browser = await puppeteer.connect({
browserWSEndpoint: `ws://0.0.0.0:8080`, // <-- connect to a server running somewhere
ignoreHTTPSErrors: true
});
const pagesCount = (await browser.pages()).length;
const browserWSEndpoint = await browser.wsEndpoint();
console.log({ browserWSEndpoint, pagesCount });
</script>
Server (server.js script):
const httpProxy = require("http-proxy");
const host = "0.0.0.0";
const port = 8080;
async function createServer(WSEndPoint, host, port) {
await httpProxy
.createServer({
target: WSEndPoint, // where we are connecting
ws: true,
localAddress: host // where to bind the proxy
})
.listen(port); // which port the proxy should listen to
return `ws://${host}:${port}`; // ie: ws://123.123.123.123:8080
}
const puppeteer = require("puppeteer");
puppeteer.launch().then(async browser=>{
const pagesCount = (await browser.pages()).length; // just to make sure we have the same stuff on both place
const browserWSEndpoint = await browser.wsEndpoint();
const customWSEndpoint = await createServer(browserWSEndpoint, host, port); // create the server here
console.log({ browserWSEndpoint, customWSEndpoint, pagesCount });
})
Run server script: node server.js. Server seems properly created. Terminal log:
browserWSEndpoint: 'ws://127.0.0.1:57640/devtools/browser/58dda865- b26e-4696-a057-25158dbc4093',
customWSEndpoint: 'ws://0.0.0.0:8080',
pagesCount: 1
npm start (from new terminal to assure the created server does not terminate)
I obtain the error in the client:
WebSocket connection to 'ws://0.0.0.0:8080/' failed:
(anonymous) # puppeteer-web:13354
I just want to use puppeteer with this front end library together in my app, fetching data with puppeteer to display it the UI and provide the user input back to puppeteer.
My ideal solution would be number 1, where I would be able to use any npm package apart from puppeteer and communicate from the backend(node server) to the client (imgui user interface) back and forth.
Thanks for any help.
EDIT:
I more less achieved it with the node server solution server which is my desired scenario, with expressjs and nodemon, running a different server in the application and communicationg with the app. Now I would find more valuable any help on:
1.- The browserifying solution and or insight about why my attempts with this approach failed.
2.- The solution that keeps everything in the one same server, that would be the server that in the repo serves the html to the browser with "start-example-html": "http-server -c-1 -o example/index.html". Dont know if that is possible. Its because I would not lose the life loading etc if I serve both things with my expressjs server added by myself.
Kind of what Create React App does with Proxying API Requests
3.- As suggested in the comments, guidance or solution to make the server code render a window through node with the imgui output (npm start-example-node) of course would be a valid answer to the question.
Seems not quite correct to change the question conditions during the bounty with a bit of a broad new scenario, but now that conditions has changed so I try to make the most of the investment and the research already done in the topic, also due to my lack of expertise in the wev-dev module bundling configuration area, so bounty may be granted for the most valuable advice in any of the two topics mentioned above. Thanks for your understanding.
We have recently upgraded from Node 0.12.2 to 8.10.0 on our test server. We are now getting -4048 EPERM when we try to export a Json file. So we went back to the previous version of Node and we are getting the same error! We can write files to that directory from windows and also have created a small node js file to write files to the remote server and it works. We have tried completely removing node and reinstalling (including several server reboots and got nowhere). We initially tried npm cache clear (--force) in both powershell and cmd at admin level after reading several posts and this did not work. The test server is not open so we cannot run npm install for example against package.json. Has anyone had a similar problem?
var fs = require('fs');
fs.writeFile("/tmp/test", "Hey there!", function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
The account the node service was running on was the wrong one and didn't have permissions for the remote server - simple as.
I've a package.json on which I define a debug script. This script launches a node app.
The whole npm script is being launched by a test, and this last one must kill the debug script once the test ends.
So when I spawn npm run debug and I kill it, the node process isn't killed.
I've tried to either kill the whole process with child_process.kill and spawning a kill bash command with no luck since the pid doesn't belong to the node launched using npm run debug.
How to kill that node process for which I don't own its pid?
You don't have to necessarily own the PID to be able to kill it (as long as the user running the scripts has permission to do it).
You could spawn commands and do it like you would in command-line (of which there are a number of ways). There are also packages like find-process which you can use to find the process that way as well.
An even easier way is to write some file that has the pid in it when debug starts up (if you can). Then you can just read that file back in to get the PID.
// in debug
import { writeFile } from 'fs';
writeFile('debug.pid', process.pid, 'utf8', err => err && console.log('Error writing pid file'));
// in app where it'll kill
import { readFile } from 'fs';
let debugPid;
readFile('debug.pid', 'utf8', (err, data) => err ? console.log('Error reading pid file') : debugPid = data);
Regardless of approach, once you have the PID, use process.kill() to kill it:
process.kill(pid);
I've been trying to get my nodejs server process to be monitored by supervisor, however I'm having issues getting supervisord.conf to work. When I deploy, I get the following error:
WARNING: The service crashed at startup or is listening to the wrong port. It failed to respond on port "node" (42801) within 30 seconds. Please check the application logs.
However when I ssh into the dotcloud server and manually start the nodejs process, it runs just fine, indicating that supervisor is failing to start the node instance.
My supervisord.conf looks like this:
[program:node]
command = node /home/dotcloud/current/app/server.js
autostart=true
autorestart=true
And my directory structure is as follows:
.dotcloudignore
dotcloud.yml
.gitignore
app/
app/package.json
app/server.js
app/supervisord.conf
At this point, I can't see what I'm doing wrong, as this appears to be the same directory structure as outlined here, so I'm kind of at a loss as to what the solution is. Any ideas?
Edit:
After trying a supervisorctl status I get the following:
node FATAL Exited too quickly (process log may have details)
I've found that in /var/log/supervisor, I'm getting the following error message:
module.js:337
throw new Error("Cannot find module '" + request + "'");
^
Error: Cannot find module '/home/dotcloud/current/app/server.js'
at Function._resolveFilename (module.js:337:11)
at Function._load (module.js:279:25)
at Array.0 (module.js:484:10)
at EventEmitter._tickCallback (node.js:190:38)
I'm not sure what is causing this.
After investigating the issue, it looks like the issue came from the fact that dotcloud.yml specified approot: app. In that case, it is useful to note that:
/home/dotcloud/code will point to the whole code repository;
/home/dotcloud/current will point to the approot (more specifically, /home/dotcloud/current will be a symlink to the approot, i.e. code/app in that case).
Therefore, supervisord.conf should not contain:
command = node /home/dotcloud/current/app/server.js
But, instead:
command = node /home/dotcloud/current/server.js
The key was in the Node.js logs themselves, since Node.js was complaining about being unable to locate /home/dotcloud/current/app/server.js.