Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to get the line number in the ejs errors? #119

Closed
IonicaBizau opened this issue Nov 4, 2015 · 36 comments
Closed

Is it possible to get the line number in the ejs errors? #119

IonicaBizau opened this issue Nov 4, 2015 · 36 comments

Comments

@IonicaBizau
Copy link
Contributor

I originally posted this question on StackOverflow. This is the original post:

(Suppose) I have a huge ejs file containing JavaScript snippets. When I compile it, I get the following error:

SyntaxError: Unexpected token ) in mytemplate.ejs while compiling ejs

While it's obvious there is a syntax error in my template, I can't know where the error is.

I have full access to the error object so, I was thinking if somewhere the error contains the line with the problem (in a similar way like the JavaScript engines tell you that there is a problem on a specific line).

I tried to access the err.stack field, but it only shows me the error origin (which comes from the ejs library), so that's not really helpful.

Is there a way to know where the syntax error is in the ejs file?

I'm using the ejs package.

@jmcollin78
Copy link

Same problem for me: #118
I try the compileDebug and debug=true options without success.
The only thing I found is to update the code of module to console.log the curent line....

JM.

@IonicaBizau
Copy link
Contributor Author

The only thing I found is to update the code of module to console.log the curent line....

Oh, can you give me the exact link? Thanks!!

@jmcollin78
Copy link

For my case it was at line 500 of the ejs.js file. The generateSource function.
Add a console.log('Current line : "%s"', line) at line 515 and you will see where the problem is.

@mde
Copy link
Owner

mde commented Nov 23, 2015

Would love a PR that implements this for everybody. :)

@dgofman
Copy link
Contributor

dgofman commented Dec 2, 2015

I am providing temporary solution its better than nothing

tj/ejs#212

Update node_modules\ejs\lib\ejs.js
Version 2.4.1
Line 520

, generateSource: function () {
    var self = this
      , matches = this.parseTemplateText()
      , d = this.opts.delimiter;

    if (matches && matches.length) {
      this.source = '    ; __filename = "' + this.opts.filename.replace(/\\/g,  '/') + '"\n';  //MAGIC YOU WILL AT LEAST KNOW A FILE NAME
      matches.forEach(function (line, index) {

image

@dgofman
Copy link
Contributor

dgofman commented Jan 29, 2016

Guys, please can you fix in the next release I am always loosing my workaround after NPM install

@mde
Copy link
Owner

mde commented Jan 29, 2016

Give us a PR with your workaround, and I'll be happy to merge it. This is how open source works, folks.

dgofman added a commit to dgofman/ejs that referenced this issue Feb 1, 2016
@dgofman
Copy link
Contributor

dgofman commented Feb 1, 2016

Before I provided only a workaround how can I detect a file. Now I providing complete Fix for this issue

#129

@dgofman
Copy link
Contributor

dgofman commented Feb 2, 2016

Please can someone merge PR 129

@dgofman
Copy link
Contributor

dgofman commented Feb 2, 2016

Please can you merge #129

Thanks,
David

On Thu, Jan 28, 2016 at 11:24 PM, Matthew Eernisse <[email protected]

wrote:

Give us a PR with your workaround, and I'll be happy to merge it. This is
how open source works, folks.


Reply to this email directly or view it on GitHub
#119 (comment).

@mde
Copy link
Owner

mde commented Feb 2, 2016

Very underwater with work. I'll definitely get to in the next day or so. Thanks for your patience!

@dgofman
Copy link
Contributor

dgofman commented Feb 6, 2016

Did you get a time to look my changes?

@IonicaBizau
Copy link
Contributor Author

@dgofman Nice work, but my issue is saying that when having unexpected error we don't get the line number.

For example, put this in body.html:

<p><%= var %></p>

Then in the browser we get:

SyntaxError: Unexpected token var in /home/ionicabizau/Documents/ejs/sample/index.html while compiling ejs
   at Function (native)
   at Object.Template.compile (/home/ionicabizau/Documents/ejs/lib/ejs.js:485:12)
   at Object.compile (/home/ionicabizau/Documents/ejs/lib/ejs.js:289:16)
   at handleCache (/home/ionicabizau/Documents/ejs/lib/ejs.js:148:16)
   at View.exports.renderFile [as engine] (/home/ionicabizau/Documents/ejs/lib/ejs.js:358:14)
   at View.render (/home/ionicabizau/Documents/ejs/node_modules/express/lib/view.js:126:8)
   at tryRender (/home/ionicabizau/Documents/ejs/node_modules/express/lib/application.js:639:10)
   at EventEmitter.render (/home/ionicabizau/Documents/ejs/node_modules/express/lib/application.js:591:3)
   at ServerResponse.render (/home/ionicabizau/Documents/ejs/node_modules/express/lib/response.js:961:7)
   at /home/ionicabizau/Documents/ejs/sample/index.js:7:6

So, we don't get the line number.
But I think it can be improved. 👍

@k1r0s
Copy link

k1r0s commented Feb 8, 2016

An easy trick to know where ejs template broke.

enable pause exceptions on chrome debugger (F12, script tab).

U will see that it stops processing here:

try {
      fn = new Function(opts.localsName + ', escape, include, rethrow', src);
    }
    catch(e) {
      // istanbul ignore else
      if (e instanceof SyntaxError) {
        if (opts.filename) {
          e.message += ' in ' + opts.filename;
        }
        e.message += ' while compiling ejs';
      }
      throw e;
    }

evaluate in console the "src" val. Then u will see the trace. Now you can click on the place where template got stuck. VMXXX:58 <--- click here

@dgofman
Copy link
Contributor

dgofman commented Feb 8, 2016

@ciroreed You solution shouldn't work. @IonicaBizau I fixed issue in code related in template. But your in compilation error (Syntax Error) handling outside template try/catch block. When I will get a time I will deep look how to fix it. Currently I don't have experiences writing invalid JavaScript code :)

@IonicaBizau
Copy link
Contributor Author

Currently I don't have experiences writing invalid JavaScript code :)

I have a lot. 😁 These syntax errors appear when quickly writing something and obviously missing something.

I am not familiar with the ejs library code, but I think there should be an error/exception that has the stack property and that will maybe output something useful. Not sure. 💭

@TimothyGu
Copy link
Collaborator

but I think there should be an error/exception that has the stack property and that will maybe output something useful.

V8 is notorious for not adding line numbers to syntax errors, so there's nothing we can do. In Jade/Pug we simply used Acorn (a JavaScript parser) to parse the code. This is of course not possible in EJS since we are trying to keep the code size down to a bare minimum.

@k1r0s
Copy link

k1r0s commented Feb 9, 2016

@dgofman my solution works because i can see line errror as i told you. Not in production environment, just for debugging

@RyanZim
Copy link
Collaborator

RyanZim commented Mar 25, 2016

@dgofman: I am looking into it.

BananaAcid pushed a commit to BananaAcid/ejs-with-exts that referenced this issue Apr 17, 2016
BananaAcid added a commit to BananaAcid/ejs-with-exts that referenced this issue Apr 17, 2016
mde added a commit that referenced this issue Apr 18, 2016
@RyanZim
Copy link
Collaborator

RyanZim commented Apr 18, 2016

@IonicaBizau PR #129 was merged. Can we close this or is there something else that needs resolved?

@dgofman
Copy link
Contributor

dgofman commented Apr 18, 2016

I cannot get latest version you didn't change in package.json new version
and pushed to NPM

https://www.npmjs.com/package/ejs

On Mon, Apr 18, 2016 at 12:16 PM, Ryan Zimmerman [email protected]
wrote:

@IonicaBizau https://github.com/IonicaBizau PR #129
#129 was merged. Can we close this or is
there something else that needs resolved?


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
#119 (comment)

@IonicaBizau
Copy link
Contributor Author

@RyanZim Probably that's a nice improvement, but still my issue is not fixed:

<h1>Users</h1>

<% foo( %>
<% //    ^ Yes, that's supposed to be there to demonstrate the error %>
<% function user(user) { %>
  <li><strong><%= user.name %></strong> is a <%= user.age %> year old <%= user.species %>.</li>
<% } %>

<ul>
  <% users.map(user) %>
</ul>

By compiling this, I get:

$ node functions.js 
/home/ionicabizau/ejs/lib/ejs.js:495
      throw e;
      ^

SyntaxError: Unexpected token ; in /home/ionicabizau/ejs/examples/functions.ejs while compiling ejs
    at Function (native)
    at Object.Template.compile (/home/ionicabizau/ejs/lib/ejs.js:485:12)
    ...

So, for a big ejs template, and such a small mistake (a missint closing )), it's very hard to debug the things. I expect to see the line number where this is crashing.

@RyanZim
Copy link
Collaborator

RyanZim commented Apr 19, 2016

@IonicaBizau It's a pain, but I don't know of much we can do. Node doesn't output line numbers when parsing JS via new Function, which is what we're doing. Here's the code:

    try {
      fn = new Function(opts.localsName + ', escape, include, rethrow', src);
    }
    catch(e) {
      // istanbul ignore else
      if (e instanceof SyntaxError) {
        if (opts.filename) {
          e.message += ' in ' + opts.filename;
        }
        e.message += ' while compiling ejs';
      }
      throw e;
    }

(See it at https://github.com/mde/ejs/blob/master/lib/ejs.js#L484-L496)

There is a bug filed for node's underlying V8 parser: https://bugs.chromium.org/p/v8/issues/detail?id=2589. It doesn't seem that this is high priority to the V8 team though. 😦

@IonicaBizau
Copy link
Contributor Author

Node doesn't output line numbers when parsing JS via new Function, which is what we're doing.

@RyanZim True. I did take a quick look at the code and my question is why do you do it this way? We have the vm module which seems to output fancy errors:

> require("vm").runInThisContext("x = 42;")
42
> require("vm").runInThisContext("x = ;")
evalmachine.<anonymous>:1
x = ;
    ^
SyntaxError: Unexpected token ;
    at Object.exports.runInThisContext (vm.js:53:16)
    at repl:1:15
    at REPLServer.defaultEval (repl.js:260:27)
    at bound (domain.js:287:14)
    at REPLServer.runBound [as eval] (domain.js:300:12)
    at REPLServer.<anonymous> (repl.js:429:12)
    at emitOne (events.js:95:20)
    at REPLServer.emit (events.js:182:7)
    at REPLServer.Interface._onLine (readline.js:211:10)
    at REPLServer.Interface._line (readline.js:550:8)
> require("vm").runInThisContext("foo(")
evalmachine.<anonymous>:1
foo(
   ^
SyntaxError: Unexpected end of input
    at Object.exports.runInThisContext (vm.js:53:16)
    at repl:1:15
    at REPLServer.defaultEval (repl.js:260:27)
    at bound (domain.js:287:14)
    at REPLServer.runBound [as eval] (domain.js:300:12)
    at REPLServer.<anonymous> (repl.js:429:12)
    at emitOne (events.js:95:20)
    at REPLServer.emit (events.js:182:7)
    at REPLServer.Interface._onLine (readline.js:211:10)
    at REPLServer.Interface._line (readline.js:550:8)

Maybe using vm would be a solution.

@RyanZim
Copy link
Collaborator

RyanZim commented Apr 19, 2016

why do you do it this way?

I don't know, perhaps @mde or @TimothyGu does.

As far as the vm module, If you can figure out a way to do it, I would welcome a PR.

@IonicaBizau
Copy link
Contributor Author

@RyanZim On the other side I'm pretty sure it will not work in the same way in the browser unless browserify or so really has a nice solution for the vm.

@RyanZim
Copy link
Collaborator

RyanZim commented Apr 19, 2016

@IonicaBizau Yeah, hadn't thought of that. Here's browserify's vm module: https://github.com/substack/vm-browserify. Pretty sparse. And I'm still not sure vm will help much.

MarcelloDiSimone pushed a commit to MarcelloDiSimone/ejs that referenced this issue May 11, 2016
* master:
  Fix more mistakes
  Fix Mistakes
  Add warning for ejs.render(dataAndOptions)
  Document JSDoc scripts in the README
  Clarify jsdocs for filename option
  Make suggested changes
  Fix typos
  Expand Client-side Support Section
  Clarify docs on the `client` option
  Add JSDocs for IncludeCallback
  Export the internal func for escaping XML
  Improve Documentation for <%_ and _%> Fixes mde#143 Also did some cleanup in the examples.
  Add documentation for renderFile() and filename
  fixed mocha test issue
  fixed unittest
  Update ejs.js
  Update index.html
  moved sample folder
  Fixed issue mde#119
@RyanZim
Copy link
Collaborator

RyanZim commented May 11, 2016

@IonicaBizau: I gave up on getting node to output good errors and wrote an EJS Linter/Syntax Checker instead!

https://github.com/RyanZim/EJS-Lint

It's not finished, but it's a step in the right direction. It uses acorn under the hood to give good error messages with the line number included.

In the example you gave [https://github.com//issues/119#issuecomment-211714702], it would say that the error is at line 10, since that is the first piece of JS after the error. Not perfect, but better than no line number.

CC: @mde @TimothyGu

@IonicaBizau
Copy link
Contributor Author

@RyanZim That sounds good! 👍

@mde
Copy link
Owner

mde commented May 24, 2016

Fixed by #129

@mde mde closed this as completed May 24, 2016
@IonicaBizau
Copy link
Contributor Author

@mde Was this really fixed? That pull request is related but it does not fix the issue, from what I know.

@RyanZim
Copy link
Collaborator

RyanZim commented May 24, 2016

@IonicaBizau

That pull request is related but it does not fix the issue, from what I know.

You are correct. I don't think this is something we can fix in the ejs core; that's why I created EJS-Lint.

I was thinking that sometime in the future I might make ejs console.log() a message like:

If the above error is not helpful, you may want to try ejs-lint

when ejs logs a js syntax error. (Of course, that's if @mde is OK with that)

Right now, EJS-Lint isn't fully featured enough for that.

@IonicaBizau
Copy link
Contributor Author

@RyanZim Ah, indeed! 👍 Maybe the error message should be updated with something like use ejs-lint to find the source of error––or so. 😁 Nice work!

@mde
Copy link
Owner

mde commented May 24, 2016

Happy to reopen, if it's something we can really fix -- @RyanZim, should this be reopened?

@RyanZim
Copy link
Collaborator

RyanZim commented May 24, 2016

@mde Nope, I'll open a new issue when EJS-Lint is mature enough. Meanwhile PR's are welcome at https://github.com/RyanZim/EJS-Lint. 😉

@Meignanam
Copy link

guys, could you help me , which kind of error , i am getting lag perticular issue

SyntaxError: Unexpected token '/' in E:\PASSPORT\views\register.ejs while compiling ejs

If the above error is not helpful, you may want to try EJS-Lint:
https://github.com/RyanZim/EJS-Lint
Or, if you meant to create an async function, pass async: true as an option.
at new Function ()
at Template.compile (E:\PASSPORT\node_modules\ejs\lib\ejs.js:661:12)
at Object.compile (E:\PASSPORT\node_modules\ejs\lib\ejs.js:396:16)
at handleCache (E:\PASSPORT\node_modules\ejs\lib\ejs.js:233:18)
at tryHandleCache (E:\PASSPORT\node_modules\ejs\lib\ejs.js:272:16)
at View.exports.renderFile [as engine] (E:\PASSPORT\node_modules\ejs\lib\ejs.js:489:10)
at View.render (E:\PASSPORT\node_modules\express\lib\view.js:135:8)
at tryRender (E:\PASSPORT\node_modules\express\lib\application.js:640:10)
at Function.render (E:\PASSPORT\node_modules\express\lib\application.js:592:3)
at ServerResponse.render (E:\PASSPORT\node_modules\express\lib\response.js:1012:7)

Repository owner locked as resolved and limited conversation to collaborators Jul 15, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants