Controlling failure on checking jinja2 variable

Hi

One of my suites has a jinja2 section at the start of the suite.rc file which does a lot of variable setting based on other jinja2 variables set elsewhere (in a rose-suite.conf). A simplified version of part of it would look something like

{% if SUITE_RESOLUTION == “low” %}
{% set GL_UM_RES = “n320e” %}

{% elif SUITE_RESOLUTION == “medium” %}
{% set GL_UM_RES = “n640e” %}

{% elif SUITE_RESOLUTION == “high” %}
{% set GL_UM_RES = “n1280e” %}

{% else %}

{% endif %}

If I happen to set a non-valid value of SUITE-RESOLUTION then cylc validate will crash out as expected but with a non-helpful (for the general user) error message. Is there a way of getting cylc validate to raise an error with a meaningful message? I doubt there is but I thought I would ask of the wise.
If not does anyone have any other suggestions as to how to make the desired failure less of a mess? Something in the {% else %} section perhaps?

Thanks

Mike

Hi @mikethurlow,

I’m not sure I see the problem. From what you’ve written, there isn’t any “non-valid value of SUITE_RESOLUTION” because you have an {% else %} block to catch everything other than “low”, “medium”, and “high”. The only way I can trigger a Jinja2 error is to not set SUITE_RESOLUTION at all, which results in a pretty clear message:

Jinja2Error:
  File "<template>", line 2, in top-level template code
UndefinedError: 'SUITE_RESOLUTION' is undefined
Context lines:
{% if SUITE_RESOLUTION == "low" %}	<-- Jinja2Error

Do you mean the else block should abort with an error message because only low, medium, and high are valid?

{% else %}
  {{ raise("invalid value of SUITE_RESOLUTION: " + SUITE_RESOLUTION) }}
{% endif %}

Then:

$ cylc validate --set="SUITE_RESOLUTION=huge" mt
Jinja2 Error: invalid value of SUITE_RESOLUTION: huge

Hilary

p.s. documentation of raise() in the current online user guide: https://cylc.github.io/doc/built-sphinx-single/index.html#raising-exceptions

1 Like

Thanks Hilary. I didn’t know about “raise” and that solves the problem!
Mike

There is also the assert function in jinja2, documented at https://cylc.github.io/doc/built-sphinx-single/index.html#assert which can be very useful.

2 Likes

Thanks Tom. I should really start thinking about jinja2 and python more holistically than I have been.

Mike

Hello Mike,

I have a similar thing in one of my rose/cylc suites. In my case I am deciding which .rc file (containing site-specific settings) to include, based on a SITE variable in the rose-suite.conf file:

{% if SITE == 'met' %}
    %include 'site_rc/suite-runtime-met.rc'
{% elif SITE == 'uni' %}
    %include 'site_rc/suite-runtime-uni.rc'
{% elif SITE == 'ofc' %}
    %include 'site_rc/suite-runtime-ofc.rc'
{% else %}
    {{ "ERROR: unknown SITE value!"/0 }}
{% endif %}

When validating with an invalid SITE value you’ll see that as an ERROR in the shell.
Not very elegant, but it works as a reminder.

1 Like

Hi @fredw,

Yeah that’s another approach. It works because your Jinja2 print statement {{ "ERROR ...." }} prints a string ("ERROR ...") that is not valid a Cylc configuration item, so the config parser will abort and print the invalid line.

Hilary

Yes that approach was similar to what I was trying previously. Having a meaningful error message is important for users who don’t like/want to unpick the automatic and cryptic that cylc validate can produce in such circumstances.