Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hide extensive traceback from the user and show only relevant information #1049

Closed
tomschr opened this issue Dec 14, 2023 · 4 comments
Closed

Comments

@tomschr
Copy link

tomschr commented Dec 14, 2023

Overview Description

Thank you for all your efforts in creating and maintaining this project. 👍

Steps to Reproduce

  1. Prepare the environment:

    $ python3 --version
    Python 3.12.1
    $ mkdir /tmp/test-pybabel
    $ python3 -m venv .venv
    $ source .venv/bin/activate
    $ pip install pybabel Jinja2
    $ pip install --upgrade pip setuptools
    $ pip list
    Package    Version
    ---------- ----------
    Jinja2     3.1.2
    MarkupSafe 2.1.3
    pip        23.3.1
    pybabel    0.0.0.dev0
    setuptools 69.0.2
    
  2. Create a Jinja2 template test.html.jinja2 with the following wrong(!) content:

    <html>
      <title>{% trans %}Hello World{% trans %}</title>
      <body>
        <h1>{% trans %}Welcome!{% endtrans %}</h1>
      </body>
    </html>
  3. Create a babel.cfg file with the following content:

    [jinja2: **.html.jinja2]
    encoding = utf-8
    ignore_tags = script,style
    include_attrs = alt title summary
    keyword = trans
    silent = false
  4. Extract the translatable strings

    $ pybabel extract -F babel.cfg -o test.pot *.html.jinja2
    [... very long traceback ...]
    File "/home/tux/.pyenv/versions/3.12.1/lib/python3.12/site-packages/jinja2/environment.py", line 611, in parse
       self.handle_exception(source=source)
    File "/home/tux/.pyenv/versions/3.12.1/lib/python3.12/site-packages/jinja2/environment.py", line 936, in handle_exception
     raise rewrite_traceback_stack(source=source)
    File "<unknown>", line 2, in template
     jinja2.exceptions.TemplateSyntaxError: control structures in translatable sections are not allowed
    

Actual Results

An (ugly) traceback shown to the user (as presented in step 4).

Expected Results

I'm aware that the silent keyword in babel.cfg leads to this kind of error. However, nevertheless I see an issue when showing the complete traceback to the user:

  • It looks like pybabel itself is broken. The traceback underminds its reputability and trust.
  • It's scary. Traceback indicates there is something fundamentally wrong, although it's "only" a problem in the Jinja2 template.
  • It's too much information. Users overlook the important information.
  • It's unfriendly to the user. A user is normally not interested in which package the problem happened. The user is interested why it happened and how to solve it.

All these points make it more difficult for the user to extract the relevant information.

In my opinion, a verbose traceback output should never be shown to the user unless there is really something fundamentally wrong. A syntax problem in a Jinja2 template should not lead to this extensive traceback output and should be condensed to the important information.

In other words, I expected something more user-friendly. 🙂

For example, pybabel should show the relevant information only which is:

  • The line number where this problem occurred.
  • The problem that was found.

Here is one idea how it could be shown to the user:

$ pybable extract ...
jinja2.exceptions.TemplateSyntaxError (line 2): control structures in translatable sections are not allowed

The real output is subject for another discussion. 😉 But I think you get the idea.

If you want to make it even more useful, suggest a solution to this problem:

$ pybable extract ...
inja2.exceptions.TemplateSyntaxError: line 2 control structures in translatable sections are not allowed
For more information, see <URL>.

The URL could point to a GitHub Wiki in your repo or the actual documentation. The content should show the most common problem and how to solve it. Each content should be consistent to each other and should have the same structure. For example:

Problem
Control structures in translatable sections are not allowed

Cause
Pybabel found ...

Solution
Try the following steps to find the root cause:
1. First step
2. Second step
3. Third step

Reproducibility

See above.

Additional Information

n/a

@akx
Copy link
Member

akx commented Dec 15, 2023

Thank you for the comprehensive issue report!

As an aside, pybabel is an unrelated (and evidently abandoned) project; we're babel and our CLI tool happens to be named pybabel for some historical reasons I'm not aware of.

Given Babel is fundamentally a technical tool aimed at somewhat technical users, I'd rather not try to smooth over the long error, lest we end up with a babel did an oopsie woopsie situation.

I'd also rather not try to be clever about redacting the traceback, since more often than not it offers valuable clues as to what has actually gone wrong when an user reaches out to the Babel folks – asking the user to re-run the command with something like --verbose-traceback or whatever sounds like more trouble than it's worth too.

Not to shift blame but to clarify the situation, the actual error you're seeing here stems from Jinja, as it's trying to parse your template:
https://github.com/pallets/jinja/blob/d594969d722ceb4e8f3da8861befc9c0ac87ae1b/src/jinja2/ext.py#L506-L508

You would get the same error without Babel in-between:

>>> import jinja2
>>> from jinja2.ext import InternationalizationExtension
>>> e = jinja2.Environment(extensions=[InternationalizationExtension])
>>> e.from_string("{% trans %}Hello World{% trans %}")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.12/site-packages/jinja2/environment.py", line 1105, in from_string
    return cls.from_code(self, self.compile(source), gs, None)
                               ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/jinja2/environment.py", line 768, in compile
    self.handle_exception(source=source_hint)
  File "/usr/local/lib/python3.12/site-packages/jinja2/environment.py", line 936, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "<unknown>", line 1, in template
jinja2.exceptions.TemplateSyntaxError: control structures in translatable sections are not allowed
>>>

It would of course be useful if that Jinja syntax error noted the name of the control structure, e.g.

jinja2.exceptions.TemplateSyntaxError: control structures in translatable sections are not allowed (saw trans)

or better yet, for this particular case,

jinja2.exceptions.TemplateSyntaxError: trans blocks may not be nested (did you mean endtrans?)

but that's not in Babel's control; adding logic that would sniff out this situation from a Jinja-specific exception and show it differently sounds brittle.

To that end, I opened a PR in Jinja that makes these errors nicer. pallets/jinja#1918

akx added a commit to akx/jinja that referenced this issue Dec 15, 2023
akx added a commit to akx/jinja that referenced this issue Dec 15, 2023
akx added a commit to akx/jinja that referenced this issue Dec 15, 2023
akx added a commit to akx/jinja that referenced this issue Dec 15, 2023
@tomschr
Copy link
Author

tomschr commented Dec 15, 2023

Thank you for your answers! Appreciated your response.

As an aside, pybabel is an unrelated (and evidently abandoned) project; we're babel and our CLI tool happens to be named pybabel for some historical reasons I'm not aware of.

Oh, I wasn't aware of that. 😲 Is there are replacement for pybabel? Anything you can recommend?

I'd also rather not try to be clever about redacting the traceback, since more often than not it offers valuable clues as to what has actually gone wrong when an user reaches out to the Babel folks – asking the user to re-run the command with something like --verbose-traceback or whatever sounds like more trouble than it's worth too.

I see what you mean. I was looking at it from a pure user point of view.

Thanks for opening an issue for the Jinja project.

Maybe in this case, I better close this issue.

Thanks for all your help! 👍

@tomschr tomschr closed this as not planned Won't fix, can't repro, duplicate, stale Dec 15, 2023
@akx
Copy link
Member

akx commented Dec 15, 2023

As an aside, pybabel is an unrelated (and evidently abandoned) project; we're babel and our CLI tool happens to be named pybabel for some historical reasons I'm not aware of.

Oh, I wasn't aware of that. 😲 Is there are replacement for pybabel? Anything you can recommend?

Oh no, what I mean is that the pybabel PyPI package is unrelated to this project and repository. This project is not abandoned.

You install the pybabel tool from this repository by running pip install babel:

# pip install babel
Successfully installed babel-2.14.0
# pybabel
Usage: pybabel command [options] [args]

pybabel: error: no valid command or option passed. Try the -h/--help option for more information.
#

c.f. installing pybabel, which does nothing of value:

# pip install pybabel
Successfully installed pybabel-0.0.0.dev0
# pybabel
bash: pybabel: command not found
#

(In fact, all that package contains is an empty babel.py file... 🤷)

@tomschr
Copy link
Author

tomschr commented Dec 16, 2023

Thanks for the clarification. Much appreciated. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants