Python 如何在Jinja2宏中引发异常?
我有一个宏,用于使用构建本地存储库 下面是代码片段:Python 如何在Jinja2宏中引发异常?,python,jinja2,salt-stack,Python,Jinja2,Salt Stack,我有一个宏,用于使用构建本地存储库 下面是代码片段: {%- set gnupghome = kwargs.pop('gnupghome', '/root/.gnupg') %} {%- set env = { 'GNUPGHOME': gnupghome } %} keyring_import: cmd: - run {%- if 'keyid' in kwargs and 'keyserver' in kwargs %} {%- set keyid = kwargs.po
{%- set gnupghome = kwargs.pop('gnupghome', '/root/.gnupg') %}
{%- set env = { 'GNUPGHOME': gnupghome } %}
keyring_import:
cmd:
- run
{%- if 'keyid' in kwargs and 'keyserver' in kwargs %}
{%- set keyid = kwargs.pop('keyid') %}
{%- set keyserver = kwargs.pop('keyserver') %}
- name: 'gpg --no-default-keyring --keyring {{ gnupghome }}/trustedkeys.gpg --keyserver {{ keyserver }} --recv-keys {{ keyid }}'
{%- elif 'key_url' in kwargs %}
{%- set key_url = kwargs.pop('key_url') %}
- name: 'wget -q -O- "{{ key_url }}" | gpg --no-default-keyring --keyring {{ gnupghome }}/trustedkeys.gpg --import'
{%- endif %}
- require:
- pkg: wget
- pkg: gnupg
在endif
关键字处,我想使用else
引发异常,例如:
需要密钥url或密钥服务器和密钥ID
有可能吗?这可以在扩展中处理。从 将扩展传递给您的环境:
jinja2.Environment(…extensions=[RaiseExtension])
然后在模板中使用它:
{%- if 'keyid' in kwargs and 'keyserver' in kwargs %}
...
{%- else %}
{% raise "Either key_url or both keyserver and keyid required." %}
{% endif %}
{{ raise("uh oh...") }}
塞雷内维院长的回答很优雅。下面是一个较短的解决方案,它为jinja的环境添加了一个全局变量
def raise_helper(msg):
raise Exception(msg)
env = jinja2.Environment(...
env.globals['raise'] = raise_helper
然后在模板中:
{%- if 'keyid' in kwargs and 'keyserver' in kwargs %}
...
{%- else %}
{% raise "Either key_url or both keyserver and keyid required." %}
{% endif %}
{{ raise("uh oh...") }}
超级快速的解决方法,只要您不介意引发
ZeroDivisionError
:
在要引发异常的任何位置插入一个{{0/0}
。插入一个{{“此处解释的我的错误”/0}
表达式。e、 g
{% if not required_parameter %}
{{ "required_parameter must be defined."/0 }}
{% endif %}
(基于zsero的0/0答案)如果这是由Ansible完成的,Ansible会将过滤器添加到Jinja,可用于:
{{ ('OK text' if condition_ok) | mandatory('Text of error message') }}
给出了失败的原因:
fatal: [hostname]: FAILED! => {"msg": "Text of error message"}
(用您需要进行的检查来替换
条件\u ok
;'ok text'
可以是'
)我还想从jinja2模板中抛出一个异常,并显示一条错误消息,但是没有任何外部依赖项(全局/扩展)。我最终得到了这个宏:
{% macro abort(error) %}
{{ None['[ERROR] ' ~ error][0] }}
{% endmacro %}
使用:
{{ abort("Either key_url or both keyserver and keyid required.") }}
它提供了一个堆栈跟踪,但有以下异常:
jinja2.exceptions.UndefinedError: 'None' has no attribute '[ERROR] Either key_url or both keyserver and keyid required.'
另一个打印给定值的快速破解:
{% include 'error: ' ~ value_to_print %}
结果:
jinja2.exceptions.TemplateNotFound: error: abc
不,Jinja2不支持引发异常。您可以使用python函数或筛选器,它们可以引发异常,但不能在纯Jinja中使用。这并没有真正提供一个有用的错误——对我来说,它会生成错误文本:“/:'str'和'int'不支持的操作数类型”。这是因为它非常简单。谢谢