twig.js icon indicating copy to clipboard operation
twig.js copied to clipboard

TwigException for invalid syntax crashes process, no way to catch error????

Open r3wt opened this issue 6 years ago • 6 comments

trying to render preview of email template, but i noticed anytime there was a twig syntax error process crashes.

so i created a template with invalid syntax and set out to try and capture the invalid syntax exception and handle the error appropriately, but it seems this is not possible for some reason?

my code is:


const fs = require('fs');
const Twig = require('twig');
Twig.cache(false);

function emailPreview(req,res){
    log('request for email template at /email/%s',req.params.template);
    var tpl = utils.basepath(config.mail.templatePath +'/'+ req.params.template);
    if(!utils.ext(tpl)){
        tpl +='.twig';
    }
    fs.access(tpl,(err)=>{
        if(err){
            return res.err(new Error('the template specified does not exist.'));
        }
        try{
            Twig.renderFile(tpl,config.mail.templateArguments,(err,html)=>{
                if(err){
                    log.error(err);
                    return res.err(err);
                }
                res.html(html);
            });    
        }
        catch(e){
            log.error(e);
            res.err(e);
        }    
    })
}
{# this template exists to test error handling for email preview #}
<html>
    <head>
        {# syntax on the following line is invalid #}
        <title>{{title||'test'}}</title>
    </head>
    <body>Test</body>
</html>

It seems no matter what i do, i am unable to capture the error and the process exits with error code. Please advise

r3wt avatar Dec 24 '19 22:12 r3wt

Same here https://github.com/wdes/changelog/blob/e5cee6a17041b614c5e7f633303fcd2d7c9c78a1/src/changelog.js#L123

err is null and no way to catch the error.. blocking me for 100% coverage :-1:

Here is an example: https://github.com/wdes/changelog/commit/e5c6ee295cdb5d691a689e059d4de0b32b3b9c74

cc @RobLoach

williamdes avatar Jan 26 '20 15:01 williamdes

i openned this file : node_modules/twig/twig.js and it looks like it should be this : throw new Twig.Error everywhere it is (2 places) : throw Twig.Error

Replacing it does throw a valid error now instead of crashing the process

but since the project is dead, how do we get this corrected in the package without hacking the node_modules folder ? :)

sample test file

const Twig = require('twig');

Twig.renderFile('./views/testtwig.html.twig', {foo:'bar'}, (err, html) => {
  console.log(html);
});

process.on('uncaughtException', function(err) {
    console.log('err', err)
})

rafipiccolo avatar Sep 19 '21 23:09 rafipiccolo

Does it work if you set rethrow to true in the app twig options?

willrowe avatar Aug 01 '22 14:08 willrowe

it changes behavior in the sens it emits an uncaughtException with this version (syntax is crazy :))

import Twig from "twig";

try {
    Twig.renderFile('./views/shit.html.twig', { settings: { 'twig options': {rethrow: true} }, foo: 'bar' }, (err, html) => {
        // no err !!!
        console.log(html);
    });
} catch(err) {
    // not catched neither !!!
}

process.on('uncaughtException', function (err) {
    // but it gets here. hence still causing an app reboot
    console.log('uncaughtException', err)
})

This other version results in a local catch (way better IMHO)

try {
    var template = Twig.twig({
        rethrow: true,
       data: `{# this template exists to test error handling for email preview #}
        <html>
           <head>
               {# syntax on the following line is invalid #}
                <title>{{title||'test'}}</title>
            </head>
            <body>Test</body>
        </html>`,
   }).render();
    console.log('template', template);
} catch(err) {
   // catched here !!!
   console.log('catched', err);
}

process.on('uncaughtException', function (err) {
    // nothing here
    console.log('uncaughtException', err)
})

with express it also results in uncaughtexception whatever i try. which is very bad.

    app.set('twig options', {
        rethrow: true,
    });

    router.get('/test', async (req, res, next) => {
        try {
            // causes a uncaughtexception
            res.render('test');

           // same
           res.render('shit', function(err, data) {
              // no err here !!!!
              res.send(data);
           });
        } catch (err) {
            res.send('catched'+err.message)
        }
    });

rafipiccolo avatar Aug 12 '22 10:08 rafipiccolo

Thanks for the additional details, this appears to be an issue with the Express specific render functions.

willrowe avatar Aug 15 '22 15:08 willrowe

Same here https://github.com/wdes/changelog/blob/e5cee6a17041b614c5e7f633303fcd2d7c9c78a1/src/changelog.js#L123

Here is an example: wdes/changelog@e5c6ee2

This is still a problem for me, I can not catch the error. That said with rethrow it's better but I still can not catch it nicely. This does "work": process.on('uncaughtException'

See my commit where I added an unit test and rethrow: https://github.com/wdes/changelog/commit/317ded3a0fe9eb7e1ffd639c72114cdfe5403f5e

williamdes avatar Sep 04 '22 20:09 williamdes