[Scons-users] Scons swallowing exception stack trace for jinja2.exceptions.TemplateNotFound
Mats Wichmann
mats at wichmann.us
Tue May 14 10:04:23 EDT 2024
On 5/13/24 22:16, Samir Mahaboob Khan Kagadkar via Scons-users wrote:
> Hi SCons Team,
>
> I use the Jinja2 templating language
> (https://jinja.palletsprojects.com/en/3.1.x/
> <https://jinja.palletsprojects.com/en/3.1.x/>) to generate scripts from
> within SCons.
>
> Jinja2 raises the TemplateNotFound (jinja2.exceptions.TemplateNotFound)
> exception when, say, a file included in the template cannot be found.
>
> Unfortunately scons does not show the exception stack trace when this is
> raised as part of a builder.
>
> Here is a simple SConstruct that demonstrates this:
>
> import jinja2
>
> def small_builder(target, source, env):
>
> raise jinja2.exceptions.TemplateNotFound("You should see this
> message")
>
> env=Environment()
>
> env.Command(['dummy/TEST.COMPLETE'], [], small_builder, chdir=0)
>
> Here is the output not showing any stack trace:
>
> $ scons -f <path_to_sconstruct_dir>/SConstruct dummy/TEST.COMPLETE
>
> scons: Reading SConscript files ...
>
> scons: done reading SConscript files.
>
> scons: Building targets ...
>
> small_builder(["dummy/TEST.COMPLETE"], [])
>
> scons: done building targets.
>
> The TemplateNotFound can be raised in a simple standalone python3 script
> invocation:
>
> import jinja2
>
> raise jinja2.exceptions.TemplateNotFound("You should see this message")
>
> with the below output
>
> $ python3 test1.py
>
> Traceback (most recent call last):
>
> File "test1.py", line 2, in <module>
>
> raise jinja2.exceptions.TemplateNotFound("You should see this message")
>
> jinja2.exceptions.TemplateNotFound: You should see this message
>
> Other exceptions work in SCons builders, of course. For example:
>
> import jinja2
>
> def small_builder(target, source, env):
>
> #raise jinja2.exceptions.TemplateNotFound("You should see this
> message")
>
> raise ValueError("You should see this message")
>
> env=Environment()
>
> env.Command(['dummy/TEST.COMPLETE'], [], small_builder, chdir=0)
>
> with the following output:
>
> scons: Reading SConscript files ...
>
> scons: done reading SConscript files.
>
> scons: Building targets ...
>
> small_builder(["dummy/TEST.COMPLETE"], [])
>
> scons: *** [dummy/TEST.COMPLETE] ValueError : You should see this message
>
> Traceback (most recent call last):
>
> File “<….>/SCons/Action.py", line 1441, in execute
>
> result = self.execfunction(target=target, source=rsources, env=env)
>
> File "<….> /SConstruct", line 5, in small_builder
>
> raise ValueError("You should see this message")
>
> ValueError: You should see this message
>
> scons: building terminated because of errors.
>
> Could you please take a look?
SCons has a routine which tries to synthesize a BuildError exception
upon detecting other exceptions that may have been raised during the
call to the action function. If doesn't do that right for the jinja
template exception - which I see is itself synthesized. I don't really
see how to cause it to do better at the moment.
convert_to_BuildError recognizes the template error as an instance of
IOError. In that case it tries to do this:
filename = getattr(status, 'filename', None)
strerror = getattr(status, 'strerror', str(status))
errno = getattr(status, 'errno', 2)
buildError = BuildError(
errstr=strerror,
status=errno,
exitstatus=2,
filename=filename,
exc_info=exc_info)
the TemplateNotFound has all three attributes that are checked for - set
to None, so the getattr defaults aren't used. The BuildError thus ends
up with an error message and status of None, which not surprisingly,
doesn't yield any interesting message.
I suppose the attribute check could be a little more pedantic, like this:
strerror = getattr(status, 'strerror', None)
if strerror is None:
strerror = str(status)
@bdbaddog - any thoughts?
More information about the Scons-users
mailing list