Closed skwde closed 7 months ago
That's a good point, but my answer is two-fold:
If were look at the piece of code:
on_error_fail = self.config['on_error_fail']
try:
md_template = self.env.from_string(markdown)
# Execute the jinja2 template and return
return md_template.render(**page_variables)
except Exception as error:
error_message = format_error(
error,
markdown=markdown,
page=self.page,
)
trace('ERROR', error_message)
if on_error_fail:
exit(ERROR_MACRO)
else:
return error_message
It fails just as any compiler would, at the first error, and there is no way to resume.
The best that we could do would be to keep track that it is a failure, and still try to run other pages. Beside the fact that this would complicate the code, it might display a series of errors, but still without certainty that all of them were found (since there might be more than one error per page).
As mentioned earlier, the purpose is to stop the build process with an indication of where to start from to debug, not to fully debug the website.
The prescribed way to debug an MkDocs website mirrors any other piece of code that could break during a build process. The offending piece of code must be analysed, debugged and run through its own "unit" testing, until all bugs are found and weeded out.
In that particular case, the testing tool of choice would be mkdocs serve
. In that case on_error_fail
should indeed be set to false
so that one could observe as many errors as possible.
Thanks for your comments.
Wouldn't be a way around this to report the 'errors' as 'warnings' to mkdocs
and have the --strict
mode deal with that?
--strict
would still fail at the first warning? Also, plugins can always raise some spurious warnings which could make the build process unreliable?
More generally, the behavior of MkDocs-Macros is built on the arguments that can be given to the Jinja2 environment.
I used a simple approach, but going beyond that would require some more serious thought.
One could perhaps define a new subclass of Undefined
that stores all errors into a file or output them as warnings, and then it would call a graceful failure at the end? 🤔
I would like it if someone else studied a solution and proposed it; as long as it doesn't change the rest of the plugin's logic.
Regarding --strict
:
I use
strict: true
validation:
omitted_files: warn
absolute_links: warn
unrecognized_links: warn
and the build process runs through, at the end it prints something like
There have been X warnings
after which an error is raised and the build failed. Then I can go through the log and fix the issues before running the build again.
Hmm, spurious warnings of plugins are bad and somehow spoil this approach.
Perhaps we are getting philosophical here, but the point with warnings, is that they were defined in Python as distinct from Exceptions, so as to continue the execution:
Warning messages are typically issued in situations where it is useful to alert the user of some condition in a program, where that condition (normally) doesn’t warrant raising an exception and terminating the program. For example, one might want to issue a warning when a program uses an obsolete module.
A strict
policy may be warranted in an environment where the developpers have control on each component of the ecosystem and are willing/able to enforce high standards of quality. DevOps usually deals with highly heterogenous material from different internal teams and external sources; so one should strike a delicate balance between catching errors that would affect production, and not being overly demanding on formal requirements (since one would make it too difficult/time-consuming to achieve a new build). So, my impression is that strict
would be too demanding in most cases, unless one is making the conscious choice of reducing the number of MkDocs components one is allowing (and therefore features, ease of use or development, etc.) for the sake of reliability.
Which is why I would prefer to (ideally) provide solutions about stopping/not-stopping that rely on exceptions; then letting the user (DevOp) decide what they want to catch or not.
Well in python this makes sense, but we are talking about mkdocs (even though your plugin is written in python).
strict
already in devops makes sense, because
mkdocs serve
whenever a change in the docs is done, is just not feasible, because
From my perspective the quickest / easiest way to write documentation is to 'just' write it have it built and then fix all the errors in one go.
I understand, though in my mind the job of the running mkdocs build
(strict or not) is to ensure that it runs; it is not a debug tool. If it doesn't (as in an exam: one error means there are likely others), it should be sent back to whomever is in charge and they should fix their work in their prefered way. Waiting for the project build to fail, to detect an error in the MkDocs website would be too late on the production chain.
If there disagreement on this, it is a question that might be deferred to the MkDocs project? 🤔
You are right, if there is one error, there are likely more. Why making it hard / inconvenient to see all errors?
Imagine if it is sent back to you, you probably also prefer to see all the errors immediately rather than having to set up your own environment first in order to see and fix all issues.
Having all build errors displayed rather than only the first error is just more convenient. Don't you agree?
I understand but unfortunately that is not the way Jinja2 and MkDocs have been implemented.
There have three options with Jinja2:
As far as I know, it is adequate for the user base and there is not a sufficient case for trying to alter that behavior at the moment.
With the
mkdocs.yml
setting inwe have the option to have the mkdocs build fail on error. The build however fails exactly when the error is encountered.
When using
on_error_fail: false
one can see all the errors but the build does not failIt would be better if one could see all the logs and all the error. Otherwise one can only fix one error and build again to see the next error.