How to raise exception in Jinja2 macro?

I have a macro that is used to create a local repository using debmirror .

Here's the code snippet:

 {%- 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 

In the endif key, I would like to use else to throw an exception, for example, for example:

Either key_url or both key servers and keyid are required.

Is it possible?

+6
source share
4 answers

A super quick workaround if you don't mind raising a ZeroDivisionError :

Insert {{ 0/0 }} wherever you want to throw an exception.

+6
source

This can be handled in the extension. From 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) 

Pass the extension to your environment: jinja2.Environment(... extensions=[RaiseExtension]) , then use it in your template:

 {%- if 'keyid' in kwargs and 'keyserver' in kwargs %} ... {%- else %} {% raise "Either key_url or both keyserver and keyid required." %} {% endif %} 
+4
source

Insert the expression {{ "My error explained here"/0 }} . eg.

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

(based on zsero 0/0 answer)

+3
source

Dean Serenevi answers elegantly. Here is a shorter solution that adds a global jinja environment.

 def raise_helper(msg): raise Exception(msg) env = jinja2.Environment(... env.globals['raise'] = raise_helper 

Then in your template:

 {{ raise("uh oh...") }} 
+1
source

All Articles