19

我有一个宏,用于使用debmirror.

这是代码片段:

{%- 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用来引发异常,例如:

需要 key_url 或 keyserver 和 keyid。

可能吗?

4

7 回答 7

21

Dean Serenevy 的回答很优雅。这是一个较短的解决方案,它为 jinja 的环境添加了一个全局。

def raise_helper(msg):
    raise Exception(msg)

env = jinja2.Environment(...
env.globals['raise'] = raise_helper

然后在您的模板中:

{{ raise("uh oh...") }}
于 2015-03-25T17:19:43.470 回答
15

超级快速的解决方法,只要您不介意提出ZeroDivisionError

{{ 0/0 }}在要引发异常的任何地方插入一个。

于 2017-04-13T17:42:44.887 回答
13

这可以在扩展中处理。来自https://github.com/duelafn/python-jinja2-apci

# FROM: https://github.com/duelafn/python-jinja2-apci/blob/master/jinja2_apci/error.py
from jinja2 import nodes
from jinja2.ext import Extension
from jinja2.exceptions import TemplateRuntimeError

class RaiseExtension(Extension):
    # This is our keyword(s):
    tags = set(['raise'])

    # See also: jinja2.parser.parse_include()
    def parse(self, parser):
        # the first token is the token that started the tag. In our case we
        # only listen to "raise" so this will be a name token with
        # "raise" as value. We get the line number so that we can give
        # that line number to the nodes we insert.
        lineno = next(parser.stream).lineno

        # Extract the message from the template
        message_node = parser.parse_expression()

        return nodes.CallBlock(
            self.call_method('_raise', [message_node], lineno=lineno),
            [], [], [], lineno=lineno
        )

    def _raise(self, msg, caller):
        raise TemplateRuntimeError(msg)

将扩展传递给您的环境:jinja2.Environment(... extensions=[RaiseExtension])然后在您的模板中使用它:

{%- if 'keyid' in kwargs and 'keyserver' in kwargs %}
    ...
{%- else %}
    {% raise "Either key_url or both keyserver and keyid required." %}
{% endif %}
于 2014-07-16T19:51:01.450 回答
9

插入{{ "My error explained here"/0 }}表达式。例如

{% if not required_parameter %}
{{ "required_parameter must be defined."/0 }}
{% endif %}

(基于 zsero 的 0/0 答案)

于 2017-07-12T22:19:51.983 回答
6

如果这是从 Ansible 完成的,Ansible 将强制过滤器添加到 Jinja,可用于执行此操作:

{{ ('OK text' if condition_ok) | mandatory('Text of error message') }}

给出失败:

fatal: [hostname]: FAILED! => {"msg": "Text of error message"}

(替换condition_ok为您需要进行的检查;'OK text'可以只是''。)

于 2020-07-13T00:54:34.413 回答
1

另一个打印给定值的快速破解:

{% include 'error: ' ~ value_to_print %}

结果:

jinja2.exceptions.TemplateNotFound: error: abc
于 2021-04-09T12:57:54.123 回答
1

我还想从 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.'
于 2021-03-09T17:06:46.073 回答