Nodejs plugin "syntax error" problem

Hi all,

I’m trying to create a snap for one of my node apps, using the nodejs plugin. I’m following the process as outlined in the tutorial at: https://tutorials.ubuntu.com/tutorial/build-a-nodejs-service

The first steps seem to go without error, until I reach the part where I do a test run of the snap, i.e.

$ my-app.node-service

This throws out the following error:

/snap/my-appr/x11/bin/my-app: 1: /snap/my-app/x11/bin/my-app: Syntax error: “(” unexpected

The code is identical to that run without any issues both in my local dev environment and deployed with Docker.

I thought this could be related to node versioning (I’ve seen examples of this error being thrown due to node version issues in the past), however I’ve specified the correct version for my app in the node-engine directive (8.5.0).

Has anyone come across this? Just wondering if it’s a known ‘gotcha’, before I dig deeper with the debug. My app is coded in typescript / ES6, but the typescript is all transpiled to .js ahead of time.

Thanks.

if my-app is a javascript file then it is likely being interpreted by the shell instead of being run through nodejs. Try your command as command: node $SNAP/bin/my-app if that is the case.

Thank you for taking the time to reply, much appreciated.

Just tried your suggestion, but that throws the following error:

/usr/bin/snap:1
(function (exports, require, module, __filename, __dirname) { ELF

SyntaxError: Invalid or unexpected token
at createScript (vm.js:74:10)
at Object.runInThisContext (vm.js:116:10)
at Module._compile (module.js:588:28)
at Object.Module._extensions…js (module.js:635:10)
at Module.load (module.js:545:32)
at tryModuleLoad (module.js:508:12)
at Function.Module._load (module.js:500:3)
at Function.Module.runMain (module.js:665:10)
at startup (bootstrap_node.js:201:16)
at bootstrap_node.js:626:3

The point of my stating “if my-app is a javascript file” was to get you to verify whether it is a javascript file before you blindly follow my suggestion. The first error indicates that the my-app file is being interpreted by another program such as BASH or nodejs and failing because the chosen interpreter is not the correct one for that file. I think you will need to show us more details about what my-app is, and what it does internally before we can help you further.

A few questions which might help:

  • is $SNAP/bin/my-app a javascript file?
  • Or, is it a binary executable?
    • if it is binary in what way does it use nodejs?
  • Does it work outside of the snap environment?
  • Are you launching it the same way in the snap as you would outside?
    • How are you launching it in both cases?
  • Have you installed all the dependent node packages?
    • Via debian package manager?
    • Or via npm
      • Globally (with npm install -g)
      • Or local to the app (without -g)

Sharing the snapcraft.yaml will probably help, too.

my-app.node-service is the file spat out by the command

sudo snap try prime/ --devmode

as per the tutorial. It is evidently a binary (I was not “blindly following” anything. I’d assumed it could be a javascript file, albeit without the explicit extension, but either way an attempt to run with node took about as long as inspecting the file to determine type - a mere matter of seconds. I posted the error so you could see the outcome for yourself, rather than take my word for it).

Never mind, I was only playing around to test the waters in any case. Seems more hassle than it’s worth - for now I’ll stick to deploying with Docker (and yes, it is deployed and works perfectly outwith the snap environment).

Thanks.

I see the tutorial now. It expects the nodejs package you install in your part section to provide a directly executable file. The chucknorris example installs a symlink in $SNAP/bin pointing to the javascript file called main.js. The reason that main.js is able to be executed is because it includes the shebang line at the top of it’s source-code (the very first line in the code block below) which tells linux what program to use as the interpreter for this file. The line in this case says to use node:

#!/usr/bin/env node

const http = require('http'),
      Chuck  = require('chucknorris-io'),
      client = new Chuck();

// ...etc

Would it be ok for you share the snapcraft.yaml?

my-app.node-service is a different file to $SNAP/bin/my-app. The former will exist in /snap/bin while the latter is inside the snap’s filesystem in the compressed container. The my-app.node-service will chain to a wrapper script in the snap’s root with a .wrapper extension which will then itself chain to the command that you specified in command: stanza of your yaml. Those steps are fine, and it is the file in $SNAP/bin/my-app after being chained by the .wrapper script which is failing to be loaded by the relevant interpreter.

1 Like

@lucyllewy i am getting same error,
snap/hawk/x3/bin/HAWK-Server: 5: /snap/hawk/x3/bin/HAWK-Server: Syntax error: “(” unexpected
Sep 26 12:42:15 arastu25 systemd[1]: snap.hawk.hawk.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
Sep 26 12:42:15 arastu25 systemd[1]: snap.hawk.hawk.service: Unit entered failed state.
Sep 26 12:42:15 arastu25 systemd[1]: snap.hawk.hawk.service: Failed with result ‘exit-code’.
Sep 26 12:42:15 arastu25 systemd[1]: snap.hawk.hawk.service: Service hold-off time over, scheduling restart.
Sep 26 12:42:15 arastu25 systemd[1]: Stopped Service for snap application hawk.hawk.
Sep 26 12:42:15 arastu25 systemd[1]: snap.hawk.hawk.service: Start request repeated too quickly.
Sep 26 12:42:15 arastu25 systemd[1]: Failed to start Service for snap application hawk.hawk.
Sep 26 14:46:12 arastu25 systemd[1]: Stopped Service for snap application hawk.hawk.
Sep 26 16:09:33 arastu25 systemd[1]: Stopped Service for snap application hawk.hawk.

bellow is my snapcraft.yml file content:

name: hawk
version: '0.1'
summary: HAWK Server
description: |
  To start HAWK server run bellow command
  $ hawk

grade: stable # must be 'stable' to release into candidate/stable channels
confinement: strict # use 'strict' once you have the right plugs and slots

apps:
  hawk:
    command: node ./bin/server.js
    daemon: simple
    restart-condition: always
    plugs: [network-bind]
    
parts:
  hawk:
    plugin: nodejs
    source: .

also added "bin": "./bin/server.js" in my package.json file of server.

can you help me to solve this problem ?

thanks,
jaydip

I can see two things that contradict themselves:

and

Your built snap seems to actually be attempting to run a file at bin/HAWK-Server which is not node ./bin/server.js. You need to figure out which of these it is supposed to be, correct the error, and try again.

As I pointed out above, if you’re running a file directly (./foo/example.js) instead of through node (node ./foo/example.js) then you need to add a shebang line to your script or the system will attempt to run it through /bin/sh which doesn’t understand javascript.

Thanks @lucyllewy, i made changes in snapcraft.yml file and my server.js file doesn’t include #!/usr/bin/env node line as it is javascript file.

command: node ./bin/server.js

it throws error

Sep 27 19:02:39 arastu25 systemd[1]: Started Service for snap application testnode.testnode.

Sep 27 19:02:39 arastu25 testnode.testnode[17274]: module.js:478
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: throw err;
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: ^
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: Error: Cannot find module ‘/snap/testnode/x1/bin/server.js’
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: at Function.Module._resolveFilename (module.js:476:15)
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: at Function.Module._load (module.js:424:25)
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: at Module.runMain (module.js:611:10)
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: at run (bootstrap_node.js:394:7)
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: at startup (bootstrap_node.js:160:9)
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: at bootstrap_node.js:507:3

so as u mentioned in above conversation i changed that line snapcraft.yml file

command: node $SNAP/bin/server.js

but still i am getting same error

Sep 27 19:02:39 arastu25 systemd[1]: Started Service for snap application testnode.testnode.

Sep 27 19:02:39 arastu25 testnode.testnode[17274]: module.js:478
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: throw err;
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: ^
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: Error: Cannot find module ‘/snap/testnode/x1/bin/server.js’
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: at Function.Module._resolveFilename (module.js:476:15)
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: at Function.Module._load (module.js:424:25)
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: at Module.runMain (module.js:611:10)
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: at run (bootstrap_node.js:394:7)
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: at startup (bootstrap_node.js:160:9)
Sep 27 19:02:39 arastu25 testnode.testnode[17274]: at bootstrap_node.js:507:3
Sep 27 19:02:39 arastu25 systemd[1]: snap.testnode.testnode.service: Main process exited, code=exited, status=1/FAILURE

Later, i renamed server.js file to www and add #!/usr/bin/env node line to top of file

and edit snapcraft.yml

command: hawk

and in package.json file i have added,

  "bin": "./bin/www",

i create snap with above changes and run it. It is working fine.

right now, i am able to run my node js service from snap. but i don’t know why first scenario is not working. any idea ??

Well, this solved my issue. always always always use a shebang.