Launchd Bash and Node - node.js

I have a script as a .plist registered in /Library/LaunchDaemons - on a particular IO event, this script triggers a bash script that lives in /usr/local/bin (root:admin 0755).
Bash script runs a nodejs script
This is the bash script:
if [[ $(ioreg -p IOUSB | grep Realforce -c) > 0 ]]; then
echo "Realforce is present"
echo 1
echo $(node ./lgtvcontrol/TVinputChange.js mac)
echo 2
else
echo "Realforce not detected"
fi
When I run the bash script as root I get this output:
Realforce is present
1
mac 3166798437680e8a22c7093bf294fbaf connecting connected app com.webos.app.hdmi3
2
When the bash script runs through the LaunchDaemon with UserName root, it gets this output:
Realforce is present
1
2
I don't get why LaunchDaemon fails to run the node script. Any idea or experience with this?
Thank you!!!
Edit 1:
By adding the following key to the plist, I'm able to get an error in node now.
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin/lgtvcontrol</string>
</dict>
When outputting the node error log to a file, I get this on execution:
internal/validators.js:113
throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
^
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined
at validateString (internal/validators.js:113:11)
at Object.join (path.js:1039:7)
at module.exports (/usr/local/bin/lgtvcontrol/node_modules/persist-path/index.js:9:27)
at new LGTV (/usr/local/bin/lgtvcontrol/index.js:48:16)
at LGTV (/usr/local/bin/lgtvcontrol/index.js:38:16)
at Object.<anonymous> (/usr/local/bin/lgtvcontrol/TVinputChange.js:7:33)
at Module._compile (internal/modules/cjs/loader.js:1121:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1160:10)
at Module.load (internal/modules/cjs/loader.js:976:32)
at Function.Module._load (internal/modules/cjs/loader.js:884:14) {
code: 'ERR_INVALID_ARG_TYPE'
}

Related

How to pass arguments to interactive mode?

Why doesn't this work? I am trying to invoke the REPL with some arguments.
tmp % node -- --name='jon'
node:internal/modules/cjs/loader:1042
throw err;
^
Error: Cannot find module '--name=jon'
at Module._resolveFilename (node:internal/modules/cjs/loader:1039:15)
at Module._load (node:internal/modules/cjs/loader:885:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:23:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
Node.js v18.13.0
Use node -
This means "read input from stdin" and node won't interpret the argument as a file to be read.
When node - is run in an interactive terminal, stdin will be a tty (i.e. the terminal input) so node default to the interactive session.
$ node - --name=jon
Welcome to Node.js v18.13.0.
Type ".help" for more information.
> process.argv
[
'/usr/local/bin/node',
'-',
'--name=jon'
]
Without a tty, node - expects the script to be the input:
$ echo 'console.log(process.argv)' | node - --name=jon
[ '/usr/local/bin/node', '-', '--name=jon' ]

Why does datadog lambda instrumentation return a `datadog-lambda-js/handler.handler is undefined or not exported`?

The Datadog AWS Lambda instrumentation seems unreliable to me. Every few invocations, I get the following error:
"errorType": "Runtime.HandlerNotFound",
"errorMessage": "/opt/nodejs/node_modules/datadog-lambda-js/handler.handler is undefined or not exported",
"stack": [
"Runtime.HandlerNotFound: /opt/nodejs/node_modules/datadog-lambda-js/handler.handler is undefined or not exported",
" at HandlerNotFound.ExtendedError [as constructor] (/opt/nodejs/node_modules/datadog-lambda-js/runtime/errors.js:113:28)",
" at new HandlerNotFound (/opt/nodejs/node_modules/datadog-lambda-js/runtime/errors.js:131:42)",
" at load (/opt/nodejs/node_modules/datadog-lambda-js/runtime/user-function.js:151:15)",
" at Object.<anonymous> (/opt/nodejs/node_modules/datadog-lambda-js/handler.js:65:59)",
" at Module._compile (internal/modules/cjs/loader.js:999:30)",
" at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)",
" at Module.load (internal/modules/cjs/loader.js:863:32)",
" at Function.Module._load (internal/modules/cjs/loader.js:708:14)",
" at Module.require (internal/modules/cjs/loader.js:887:19)",
" at require (internal/modules/cjs/helpers.js:74:18)"
]
}
To start the instrumentation, I run the following code.
datadog-ci lambda instrument \
-f my-lambda-name \
-r my-region \
-v 50 -e 15 \
--service my-service \
--env my-env \
--version 1.0
Any idea what I'm doing wrong?
Depending on the runtime environment, you should point to a different version of the datadog layer extensions.
Python, for example, uses -v 50 -e 15, but Node.js handlers should use a different version, -v 66 -e 16.
All of this is available in the documentation: https://docs.datadoghq.com/serverless/installation/nodejs/?tab=datadogcli

Mocha not working in WebStorm in WSL due to 'unknown \"reporter\"'

When running mocha in WebSstorm pointed to a WSL environment I get:
C:\Users\iursino\AppData\Local\Microsoft\WindowsApps\ubuntu.exe run "export PATH=/home/iursino/n/bin:$PATH && /home/iursino/n/bin/node --inspect-brk=49953 /mnt/c/workspace/redacted-project-name/node_modules/mocha/bin/_mocha --timeout 0 --ui bdd --reporter \"/mnt/c/Program Files/JetBrains/WebStorm 2019.2.4/plugins/NodeJS/js/mocha-intellij/lib/mochaIntellijReporter.js\" /mnt/c/workspace/redacted-project-name/src/Filename.spec.ts --grep \"^invoke lambda Expect error if lambda returns an error$\""
Debugger listening on ws://127.0.0.1:49953/f31007fa-106c-4847-94cf-3e7d98d72e71
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
mocha debug [spec..]
Run tests with Mocha
Rules & Behavior
--allow-uncaught Allow uncaught errors to propagate [boolean]
--async-only, -A Require all tests to use a callback (async) or
return a Promise [boolean]
--bail, -b Abort ("bail") after first test failure [boolean]
--check-leaks Check for global variable leaks [boolean]
--delay Delay initial execution of root suite [boolean]
--exit Force Mocha to quit after tests complete [boolean]
--forbid-only Fail if exclusive test(s) encountered [boolean]
--forbid-pending Fail if pending test(s) encountered [boolean]
--global, --globals List of allowed global variables [array]
--retries Retry failed tests this many times [number]
--slow, -s Specify "slow" test threshold (in milliseconds)
[number] [default: 75]
--timeout, -t, --timeouts Specify test timeout threshold (in milliseconds)
[number] [default: 2000]
--ui, -u Specify user interface [string] [default: "bdd"]
Reporting & Output
--color, -c, --colors Force-enable color output [boolean]
--diff Show diff on failure
[boolean] [default: true]
--full-trace Display full stack traces [boolean]
--growl, -G Enable Growl notifications [boolean]
--inline-diffs Display actual/expected differences
inline within each string [boolean]
--reporter, -R Specify reporter to use
[string] [default: "spec"]
--reporter-option, --reporter-options, Reporter-specific options
-O (<k=v,[k1=v1,..]>) [array]
Configuration
--config Path to config file [default: (nearest rc file)]
--opts Path to `mocha.opts` [string] [default: "./test/mocha.opts"]
--package Path to package.json for config [string]
File Handling
--exclude Ignore file(s) or glob pattern(s)
[array] [default: (none)]
--extension, --watch-extensions File extension(s) to load and/or watch
[array] [default: js]
--file Specify file(s) to be loaded prior to root
suite execution [array] [default: (none)]
--recursive Look for tests in subdirectories [boolean]
--require, -r Require module [array] [default: (none)]
--sort, -S Sort test files [boolean]
--watch, -w Watch files in the current working directory
for changes [boolean]
Test Filters
--fgrep, -f Only run tests containing this string [string]
--grep, -g Only run tests matching this string or regexp [string]
--invert, -i Inverts --grep and --fgrep matches [boolean]
Positional Arguments
spec One or more files, directories, or globs to test
[array] [default: ["test"]]
Other Options
--help, -h Show usage information & exit [boolean]
--version, -V Show version number & exit [boolean]
--interfaces List built-in user interfaces & exit [boolean]
--reporters List built-in reporters & exit [boolean]
✖ ERROR: Unknown "reporter": /mnt/c/Program Files/JetBrains/WebStorm 2019.2.4/plugins/NodeJS/js/mocha-intellij/lib/mochaIntellijReporter.js
Waiting for the debugger to disconnect...
Process finished with exit code 1
If I copy paste the first line into cmd though it runs. Seems to be an issue with quotes or something.
It doesn't work though, I get this:
C:\Users\iursino>C:\Users\iursino\AppData\Local\Microsoft\WindowsApps\ubuntu.exe run "export PATH=/home/iursino/n/bin:$PATH && /home/iursino/n/bin/node /mnt/c/workspace/project-name-redacted/node_modules/mocha/bin/_mocha --require ts-node/register --ui bdd --reporter \"/mnt/c/Program Files/JetBrains/WebStorm 2019.2.4/plugins/NodeJS/js/mocha-intellij/lib/mochaIntellijReporter.js\" /mnt/c/workspace/project-name-redacted/src/Filename.spec.ts --grep \"^invoke lambda Expect success result when invoking lambda$\""
/mnt/c/workspace/project-name-redacted/node_modules/ts-node/src/index.ts:245
return new TSError(diagnosticText, diagnosticCodes)
^
TSError: ⨯ Unable to compile TypeScript:
error TS2468: Cannot find global value 'Promise'.
../../workspace/project-name-redacted/src/Filename.spec.ts:3:8 - error TS1259: Module '"chai"' can only be default-imported using the 'esModuleInterop' flag
3 import chai, { expect } from 'chai'
~~~~
../../workspace/project-name-redacted/node_modules/#types/chai/index.d.ts:1921:5
1921 export = chai;
~~~~~~~~~~~~~~
This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag.
../../workspace/project-name-redacted/src/Filename.spec.ts:4:8 - error TS1259: Module '"chai-as-promised"' can only be default-imported using the 'esModuleInterop' flag
4 import chaiAsPromised from 'chai-as-promised'
~~~~~~~~~~~~~~
../../workspace/project-name-redacted/node_modules/#types/chai-as-promised/index.d.ts:20:5
20 export = chaiAsPromised;
~~~~~~~~~~~~~~~~~~~~~~~~
This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag.
../../workspace/project-name-redacted/src/Filename.spec.ts:9:1 - error TS2582: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i #types/jest` or `npm i #types/mocha`.
9 describe('invoke lambda', () => {
~~~~~~~~
../../workspace/project-name-redacted/src/Filename.spec.ts:25:5 - error TS2304: Cannot find name 'beforeEach'.
25 beforeEach(() => {
~~~~~~~~~~
../../workspace/project-name-redacted/src/Filename.spec.ts:30:5 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i #types/jest` or `npm i #types/mocha`.
30 it('Expect success result when invoking lambda', async () => {
~~
../../workspace/project-name-redacted/src/Filename.spec.ts:30:54 - error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.
30 it('Expect success result when invoking lambda', async () => {
~~~~~~~~~~~~~
../../workspace/project-name-redacted/src/Filename.spec.ts:39:5 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i #types/jest` or `npm i #types/mocha`.
39 it('Expect error if lambda returns an error', async () => {
~~
../../workspace/project-name-redacted/src/Filename.spec.ts:39:51 - error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.
39 it('Expect error if lambda returns an error', async () => {
~~~~~~~~~~~~~
../../workspace/project-name-redacted/src/Filename.spec.ts:48:5 - error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i #types/jest` or `npm i #types/mocha`.
48 it('Expect promise rejection if lambda returns an object as error (but not of type error)', async () => {
~~
../../workspace/project-name-redacted/src/Filename.spec.ts:48:98 - error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.
48 it('Expect promise rejection if lambda returns an object as error (but not of type error)', async () => {
~~~~~~~~~~~~~
../../workspace/project-name-redacted/src/Filename.spec.ts:57:5 - error TS2304: Cannot find name 'afterEach'.
57 afterEach(() => {
~~~~~~~~~
at createTSError (/mnt/c/workspace/project-name-redacted/node_modules/ts-node/src/index.ts:245:12)
at reportTSError (/mnt/c/workspace/project-name-redacted/node_modules/ts-node/src/index.ts:249:19)
at getOutput (/mnt/c/workspace/project-name-redacted/node_modules/ts-node/src/index.ts:357:34)
at Object.compile (/mnt/c/workspace/project-name-redacted/node_modules/ts-node/src/index.ts:415:32)
at Module.m._compile (/mnt/c/workspace/project-name-redacted/node_modules/ts-node/src/index.ts:493:43)
at Module._extensions..js (internal/modules/cjs/loader.js:787:10)
at Object.require.extensions.(anonymous function) [as .ts] (/mnt/c/workspace/project-name-redacted/node_modules/ts-node/src/index.ts:496:12)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Module.require (internal/modules/cjs/loader.js:690:17)
at require (internal/modules/cjs/helpers.js:25:18)
at /mnt/c/workspace/project-name-redacted/node_modules/mocha/lib/mocha.js:330:36
at Array.forEach (<anonymous>)
at Mocha.loadFiles (/mnt/c/workspace/project-name-redacted/node_modules/mocha/lib/mocha.js:327:14)
at Mocha.run (/mnt/c/workspace/project-name-redacted/node_modules/mocha/lib/mocha.js:804:10)
at Object.exports.singleRun (/mnt/c/workspace/project-name-redacted/node_modules/mocha/lib/cli/run-helpers.js:207:16)
at exports.runMocha (/mnt/c/workspace/project-name-redacted/node_modules/mocha/lib/cli/run-helpers.js:300:13)
at Object.exports.handler.argv [as handler] (/mnt/c/workspace/project-name-redacted/node_modules/mocha/lib/cli/run.js:296:3)
at Object.runCommand (/mnt/c/workspace/project-name-redacted/node_modules/yargs/lib/command.js:242:26)
at Object.parseArgs [as _parseArgs] (/mnt/c/workspace/project-name-redacted/node_modules/yargs/yargs.js:1087:28)
at Object.parse (/mnt/c/workspace/project-name-redacted/node_modules/yargs/yargs.js:566:25)
at Object.exports.main (/mnt/c/workspace/project-name-redacted/node_modules/mocha/lib/cli/cli.js:63:6)
at Object.<anonymous> (/mnt/c/workspace/project-name-redacted/node_modules/mocha/bin/_mocha:10:23)
at Module._compile (internal/modules/cjs/loader.js:776:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:829:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
Why is it different in cmd and WebStorm? Another question: What's up with the error I get in cmd?
Edit: uploaded the cmd output in a redacted form.

Docker :: Node Hello World Example :: SyntaxError: Invalid or unexpected token?

I am trying to run this hello world example on node within a docker container
https://medium.com/#adnanrahic/hello-world-app-with-node-js-and-express-c1eb7cfa8a30
Here is my dockerfile:
#escape=`
FROM microsoft/nanoserver
ADD https://nodejs.org/dist/v8.11.1/node-v8.11.1-win-x64.zip C:\node-v8.11.1-win-x64.zip
RUN powershell -Command Expand-Archive C:\node-v8.11.1-win-x64.zip C:\; Rename-Item C:\node-v8.11.1-win-x64 node; `
SETX PATH C:\node;
SHELL ["powershell", "-Command"]
RUN mkdir hello-world; `
cd c:\hello-world; `
npm init -f; `
(Get-Content C:\hello-world\package.json) | `
ForEach-Object { $_ -replace 'index.js', 'app.js' } | `
Set-Content C:\hello-world\package.json; `
npm install express --save; `
echo \""var express = require('express');\"" > app.js; `
echo \""var app = express();\"" >> app.js; `
echo \""app.get('/', function (req, res) {\"" >> app.js; `
echo \"" res.send('Hello World!');\"" >> app.js; `
echo \""});\"" >> app.js; `
echo \""app.listen(3000, function () {\"" >> app.js; `
echo \"" console.log('Example app listening on port 3000!');\"" >> app.js; `
echo \""});\"" >> app.js; `
del c:\node-v8.11.1-win-x64.zip
EXPOSE 3000
ENTRYPOINT node c:\hello-world\app.js
after building the container successsfully:
docker build . -t nano-node-hw
and run it, I get the following error:
PS C:\Users\user\Docker\Node> docker run -it -p 3000:3000 --name node-hello nano-node-hw
c:\hello-world\app.js:1
(function (exports, require, module, __filename, __dirname) { ??v
^
SyntaxError: Invalid or unexpected token
at createScript (vm.js:80:10)
at Object.runInThisContext (vm.js:139:10)
at Module._compile (module.js:616:28)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:188:16)
at bootstrap_node.js:609:3
I did these same steps on my laptop (Windows 10) running node locally and had no issues.. what gives??

How to deploy a phantomjs node app on AWS Lambda?

I threw together a small Lambda function together to crawl a website using the SpookyJS, CasperJS, and PhantomJS toolchain for headless browsing. The task is quite simple, and at some point a few months ago it was working in Lambda. I recently had to change a few things around and wanted to work on the project again, but started fresh and had trouble getting Lambda to run without erroring in any capacity. My question is how can I run phantomjs in Lambda?
The example code I am running is:
spooky.start('http://en.wikipedia.org/wiki/Spooky_the_Tuff_Little_Ghost');
spooky.then(function () {
this.emit('hello', 'Hello, from ' + this.evaluate(function () {
return document.title;
}));
});
spooky.run();
The error I am getting in Lambda is:
{ [Error: Child terminated with non-zero exit code 1] details: { code: 1, signal: null } }
I have followed a variety of procedures to ensure everything is able to run on Lambda. Below is a long list of things I've attempted to diagnose:
Run locally using node index.js and confirm it is working
Upload package.json and the js file to an Amazon Linux EC2 instance for compilation as recommended for npm installation calls and described here
Run npm install on the ec2 instance, and again run node index.js to ensure the correct output
zip everything up, and deploy to AWS using the cli
My package.json is:
{
"name": "lambda-spooky-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"casperjs": "^1.1.3",
"phantomjs-prebuilt": "^2.1.10",
"spooky": "^0.2.5"
}
}
I have also attempted the following (most also working locally, and on the AWS EC2 instance, but with the same error on Lambda:
Trying the non -prebuilt version of phantom
Ensuring casperjs and phantomjs are accessible from the path with process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT'] + ':' + process.env['LAMBDA_TASK_ROOT'] + '/node_modules/.bin';
console.log( 'PATH: ' + process.env.PATH );
Inspecting spawn calls by wrapping child_process's .spawn() call, and got the following:
{ '0': 'casperjs',
'1':
[ '/var/task/node_modules/spooky/lib/bootstrap.js',
'--transport=http',
'--command=casperjs',
'--port=8081',
'--spooky_lib=/var/task/node_modules/spooky/lib/../',
'--spawnOptions=[object Object]' ],
'2': {} }
Calling .exec('casperjs') and .exec('phantomjs --version') directly, confirming it works locally and on EC2, but gets the following error in Lambda. The command:
`require('child_process').exec('casperjs', (error, stdout, stderr) => {
if (error) { console.error('error: ' + error); }
console.log('out: ' + stdout);
console.log('err: ' + stderr);
});
both with the following result:
err: Error: Command failed: /bin/sh -c casperjs
module.js:327
throw err;
^
Error: Cannot find module '/var/task/node_modules/lib/phantomjs'
at Function.Module._resolveFilename (module.js:325:15)
at Function.Module._load (module.js:276:25)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at Object.<anonymous> (/var/task/node_modules/.bin/phantomjs:16:15)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
2016-08-07T15:36:37.349Z b9a1b509-5cb4-11e6-ae82-256a0a2817b9 sout:
2016-08-07T15:36:37.349Z b9a1b509-5cb4-11e6-ae82-256a0a2817b9 serr: module.js:327
throw err;
^
Error: Cannot find module '/var/task/node_modules/lib/phantomjs'
at Function.Module._resolveFilename (module.js:325:15)
at Function.Module._load (module.js:276:25)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at Object.<anonymous> (/var/task/node_modules/.bin/phantomjs:16:15)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
I found the issue to be that including the node_modules/.bin in the path works on both local and ec2 machines because those files simply point to the action /bin folders in each respective library. This breaks if calls within those files use relative paths. The issue:
[ec2-user#ip-172-31-32-87 .bin]$ ls -lrt
total 0
lrwxrwxrwx 1 ec2-user ec2-user 35 Aug 7 00:52 phantomjs -> ../phantomjs-prebuilt/bin/phantomjs
lrwxrwxrwx 1 ec2-user ec2-user 24 Aug 7 00:52 casperjs -> ../casperjs/bin/casperjs
I worked around this by adding each library's respective bin to the lambda path in the Lambda handler function:
process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT']
+ ':' + process.env['LAMBDA_TASK_ROOT'] + '/node_modules/phantomjs-prebuilt/bin'
+ ':' + process.env['LAMBDA_TASK_ROOT'] + '/node_modules/casperjs/bin';
And this will now run phantom, casper, and spooky correctly in Lambda.

Resources