diff --git a/lib/ansible/runner/action_plugins/template.py b/lib/ansible/runner/action_plugins/template.py index 623d173c095..f7ac3b34e07 100644 --- a/lib/ansible/runner/action_plugins/template.py +++ b/lib/ansible/runner/action_plugins/template.py @@ -87,7 +87,7 @@ class ActionModule(object): try: resultant = template.template_from_file(self.runner.basedir, source, inject, vault_password=self.runner.vault_pass) except Exception, e: - result = dict(failed=True, msg=str(e)) + result = dict(failed=True, msg=type(e).__name__ + ": " + str(e)) return ReturnData(conn=conn, comm_ok=False, result=result) local_md5 = utils.md5s(resultant) diff --git a/lib/ansible/utils/template.py b/lib/ansible/utils/template.py index 7848dd158ac..58fe2287cb5 100644 --- a/lib/ansible/utils/template.py +++ b/lib/ansible/utils/template.py @@ -281,6 +281,16 @@ def template_from_file(basedir, path, vars, vault_password=None): res = jinja2.utils.concat(t.root_render_func(t.new_context(_jinja2_vars(basedir, vars, t.globals, fail_on_undefined), shared=True))) except jinja2.exceptions.UndefinedError, e: raise errors.AnsibleUndefinedVariable("One or more undefined variables: %s" % str(e)) + except jinja2.exceptions.TemplateNotFound, e: + # Throw an exception which includes a more user friendly error message + # This likely will happen for included sub-template. Not that besides + # pure "file not found" it may happen due to Jinja2's "security" + # checks on path. + values = {'name': realpath, 'subname': str(e)} + msg = 'file: %(name)s, error: Cannot find/not allowed to load (include) template %(subname)s' % \ + values + error = errors.AnsibleError(msg) + raise error # The low level calls above do not preserve the newline # characters at the end of the input data, so we use the