mde / ejs

Embedded JavaScript templates -- http://ejs.co
Apache License 2.0
7.77k stars 842 forks source link

Error messages are hard to debug from Express #376

Open ericandrewlewis opened 6 years ago

ericandrewlewis commented 6 years ago

In the context of Express, say I create a template that is missing an EJS closing tag as sometimes will happen:

In views/users/index.ejs:

<div>
  <h2><%= user.name</h2>
  <p><%= user.email %></p>
</div>

I get the following error:

Error: Could not find matching close tag for "<%".
    at /Users/ericlewis/Desktop/views-lesson/node_modules/ejs/lib/ejs.js:697:19
    at Array.forEach (<anonymous>)
    at Template.generateSource (/Users/ericlewis/Desktop/views-lesson/node_modules/ejs/lib/ejs.js:678:15)
    at Template.compile (/Users/ericlewis/Desktop/views-lesson/node_modules/ejs/lib/ejs.js:557:12)
    at Object.compile (/Users/ericlewis/Desktop/views-lesson/node_modules/ejs/lib/ejs.js:389:16)
    at handleCache (/Users/ericlewis/Desktop/views-lesson/node_modules/ejs/lib/ejs.js:212:18)
    at tryHandleCache (/Users/ericlewis/Desktop/views-lesson/node_modules/ejs/lib/ejs.js:251:16)
    at View.exports.renderFile [as engine] (/Users/ericlewis/Desktop/views-lesson/node_modules/ejs/lib/ejs.js:482:10)
    at View.render (/Users/ericlewis/Desktop/views-lesson/node_modules/express/lib/view.js:135:8)
    at tryRender (/Users/ericlewis/Desktop/views-lesson/node_modules/express/lib/application.js:640:10)

This problem is hard to debug:

  1. I'm told what the problem is, but not where the problem is
  2. The callstack is abbreviated, so we don't see useful functions in the callstack that are from my code
ericandrewlewis commented 6 years ago

The second problem I think is in the Express' implementation and can't be fixed in EJS.

I think we could do something in EJS to help with the first problem and provide more context about the error.

If the template is compiled with a filename option, we could output that to get an error message like this which would be useful information to go on:

Error: Could not find matching close tag for "<%".in file:

  /Users/ericlewis/Desktop/views-lesson/views/courts/index.ejs

    at /Users/ericlewis/Desktop/views-lesson/node_modules/ejs/lib/ejs.js:697:19
    at Array.forEach (<anonymous>)
    at Template.generateSource (/Users/ericlewis/Desktop/views-lesson/node_modules/ejs/lib/ejs.js:678:15)
    at Template.compile (/Users/ericlewis/Desktop/views-lesson/node_modules/ejs/lib/ejs.js:557:12)
    at Object.compile (/Users/ericlewis/Desktop/views-lesson/node_modules/ejs/lib/ejs.js:389:16)
    at handleCache (/Users/ericlewis/Desktop/views-lesson/node_modules/ejs/lib/ejs.js:212:18)
    at tryHandleCache (/Users/ericlewis/Desktop/views-lesson/node_modules/ejs/lib/ejs.js:251:16)
    at View.exports.renderFile [as engine] (/Users/ericlewis/Desktop/views-lesson/node_modules/ejs/lib/ejs.js:482:10)
    at View.render (/Users/ericlewis/Desktop/views-lesson/node_modules/express/lib/view.js:135:8)
    at tryRender (/Users/ericlewis/Desktop/views-lesson/node_modules/express/lib/application.js:640:10)

I opened up a PR with a sample of this change in #377

ycg520520 commented 5 years ago

at lib>ejs.js ==> 709 line, 修改成这样就可以在tag出错时明确知道位置在哪里。

let errorIndex = index, prevStep = 0, prevMax = 0, nextStep = 0, nextMax = 0, errorPrevStr = '', errorNextStr = ''
            while (prevStep > -2 && prevMax < 50) {
              const stepIndex = errorIndex - prevMax -1
              errorPrevStr = matches[stepIndex] + errorPrevStr;
              if (matches[stepIndex] === '\n') {
                prevStep--
              }
              prevMax++
            }
            while (nextStep < 2 && nextMax < 2) {
              const stepIndex = errorIndex + nextMax + 1
              errorNextStr = matches[stepIndex] + errorNextStr;
              if (matches[stepIndex] === '\n') {
                nextStep++
              }
              nextMax ++
            }
            errorPrevStr = opts.filename + '\n' + errorPrevStr
            throw new Error(errorPrevStr + '\n'+ 'Could not find matching close tag for "' + line + '\n' + errorNextStr + '".');

image