SCons may convert another exception to BuildError incorrectly
An internal SCons routine, SCons.Errors.convert_to_BuildError, attempts to synthesize a BuildError exception from whatever exception may have been raised when the Taskmaster executes an action. This can go wrong in certain circumstances. The docstring for the BuildError class contains these comments:
errstr: a description of the error message
status: the return code of the action that caused the build error. Must be set to a non-zero value even if the build error is not due to an action returning a non-zero returned code.
In the case reported in the linked thread, the Jinja templating engine (used in-process) raised a jinja2.exceptions.TemplateNotFound exception, which is initialized in a kind of odd way (separate topic), where the three important exception fields filename, strerror and errno are all set to None. The conversion routine then tries this (status contains the captured exception at this point):
filename = getattr(status, 'filename', None)
strerror = getattr(status, 'strerror', str(status))
errno = getattr(status, 'errno', 2)
before stuffing those values into the BuildError instance. As written, strerror and errno will remain None if they were None in the original exception, which is not the intent of the routine, as described in the docstring (the getattr defaults only apply if the attributes are not present). The effect is that the exception appears to be "swallowed". SCons should be more tolerant of this, and get the defaults in if the fields were None.
- Mailing list reference: https://pairlist4.pair.net/pipermail/scons-users/2024-May/009349.html
- Version of SCons: 4.7.0
Simple repro:
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)