mozilla / nunjucks

A powerful templating engine with inheritance, asynchronous control, and more (jinja2 inspired)
https://mozilla.github.io/nunjucks/
BSD 2-Clause "Simplified" License
8.48k stars 634 forks source link

Errors thrown by global functions get stacktrace swallowed unless `dev` is set #1430

Open pezholio opened 1 year ago

pezholio commented 1 year ago

Hi,

I've been trying to diagnose an issue where I'm using a global function within a Nunjucks template. By default, I just get the errror:

Error:

Template render error: (/path/to/project/dist/server/views/view.njk) [Line 122, Column 58]
  Error: 
    at Object._prettifyError (/path/to/project/node_modules/nunjucks/src/lib.js:36:11)
    at /path/to/project/node_modules/nunjucks/src/environment.js:563:19
    at eval (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:633:18), <anonymous>:148:12)
    at eval (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:633:18), <anonymous>:287:12)
    at b_content (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:633:18), <anonymous>:181:3)
    at eval (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:633:18), <anonymous>:286:28)
    at b_beforeContent (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:633:18), <anonymous>:302:1)
    at b_main (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:633:18), <anonymous>:273:34)
    at eval (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:633:18), <anonymous>:147:83)
    at eval (eval at _compile (/path/to/project/node_modules/nunjucks/src/environment.js:633:18), <anonymous>:108:1)

Obviously, this is not helpful, as it doesn't dig down into the actual root cause of the error.

After digging around in the source code, I discovered these lines of code:

    // The dev flag determines the trace that'll be shown on errors.
    // If set to true, returns the full trace from the error point,
    // otherwise will return trace starting from Template.render
    // (the full trace from within nunjucks may confuse developers using
    //  the library)
    // defaults to false
    opts = this.opts = opts || {};
    this.opts.dev = !!opts.dev;

This seems to suggest that if I set the (undocumented) dev option to true. I will see a more detailed stacktrace telling me the source of the error. And lo and behold, it works!

It would be nice to change this option to showTrace or similar, as folks (like me!) may want to get a fuller trace in production so tools like Sentry etc will pick this up. I'm happy to contribute, but I don't want to leave the tests uncovered and am unsure how to even test this.

I imagine it'd be a case of something like this:

  init(loaders, opts) {
    // The showTrace flag determines the trace that'll be shown on errors.
    // If set to true, returns the full trace from the error point,
    // otherwise will return trace starting from Template.render
    // (the full trace from within nunjucks may confuse developers using
    //  the library)
    // defaults to the value of `opts.dev` or `false` if `opts.dev` is
    // not present
    opts = this.opts = opts || {};

    if (opts.showTrace) {
      this.opts.showTrace = opts.showTrace;
    } else {
      this.opts.showTrace = !!opts.dev;
    }
...

And then changing all instances of this.opts.dev to this.opts.showTrace

Thoughts welcome!