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

Improve error message for missing Markdown extensions #782

Closed
sils opened this issue Dec 30, 2015 · 13 comments
Closed

Improve error message for missing Markdown extensions #782

sils opened this issue Dec 30, 2015 · 13 comments
Labels
Milestone

Comments

@sils
Copy link

@sils sils commented Dec 30, 2015

I just had to install that manually.

@facelessuser
Copy link
Contributor

@facelessuser facelessuser commented Dec 30, 2015

Pymdown-extensions is not a required set of extensions as Mkdocs works great without them. Those extensions are just extras you can install if you like one or more of the extensions. I use them, but that is also because I wrote them :).

@sils
Copy link
Author

@sils sils commented Dec 30, 2015

Ah, because I use pymdownx.superfences explicitly! Maybe you could catch the import error and promt the user nicely for installing pymdown-extensions?

@facelessuser
Copy link
Contributor

@facelessuser facelessuser commented Dec 30, 2015

Yeah, that is really a Python Markdown thing. It is set to fail on extension import error.

@d0ugal d0ugal added the Enhancement label Jan 28, 2016
@d0ugal
Copy link
Member

@d0ugal d0ugal commented Jan 28, 2016

Yeah, okay - let's show a better error here if we can. Even if it just a nicer error that states something like this: "Your mkdocs.yml has a python-markdown extension that you don't seem to have installed locally"

It is surprisingly difficult for us to tell users what package they need to install, because: Python packaging 😄

@waylan
Copy link
Member

@waylan waylan commented Jan 28, 2016

Right. You are wrapping a library, which raises an ImportError when given a bad (or uninstalled) extension name. The tricky part is that MkDocs does not preload all of the extensions, but only passes the list of extension names on to Markdown on page build (and this happens every time for every single page built). I see three options:

  1. Wrap utils.convert_markdown in a try/except block and on ImportError stop the build process returning a friendly error. The error would occur on the first page being built. This could result in a "dirty" partially built site_dir.
  2. Have Mkdocs load the extensions itself (as part of the config validation) and raise errors then. Markdown will accept instances of extensions in addition to string names, so then just pass the instances to Markdown. Of course, this replicates some of the code already in Markdown and could be subject to change in future releases.
  3. Create a throwaway instance of the Markdown class in the config validation step and have validation fail on error. It has to be a throwaway instance because each individual page needs its own custom version of the internal (to MkDocs) RealativePathExtension (see mkdocs/commands/build.py#L28). Therefore, MkDocs can't just create one Markdown instance and reuse it for every page. To be clear, I would expect the throwaway instance to not include the RealativePathExtension. We simply need to validate that all user provided extension names are loadable/importable.

My suggestion would be 1 or 3 above. There is no mechanism in place within MkDocs to handle an error raised during build. All the error handling is relegated to the config validation, which is why I mention options 2 and 3 (not to mention the potential for a "dirty" site dir in option 1). Option 3 sees like the best fix to me.

@waylan
Copy link
Member

@waylan waylan commented Jan 28, 2016

It is surprisingly difficult for us to tell users what package they need to install, because: Python packaging

Also because many times the user simply spelled it wrong, in which case nothing needs to be installed. However, it is nearly impossible to tell which it is and writing a "friendly" error message which covers both is tricky.

@waylan
Copy link
Member

@waylan waylan commented Jan 28, 2016

A potential problem just occurred to me for both options 1 and 3 above. The error message provided by Markdown will need to be parsed to get the specific extension name which raised the error. You could just pass the message on, but that may not be "friendly".

However, I don't recommend option 2 as the upcoming version 3 of the Markdown lib will be switching to using SetupTools entry points to load extensions by name. An option 2 solution will not work across Python-Markdown versions 2.x and 3.x.

@d0ugal
Copy link
Member

@d0ugal d0ugal commented Jan 28, 2016

switching to using SetupTools entry points to load extensions by name

Neat!

@waylan waylan added this to the 1.0.0 milestone Dec 2, 2016
@waylan waylan changed the title Missing dependency: pymdown-extensions Improve error message for missing Markdown extensions Apr 4, 2018
@waylan
Copy link
Member

@waylan waylan commented Apr 6, 2018

I have a working solution for option 3 above. If an extension foo is listed in the config, I get this output:

$ mkdocs build
ERROR   -  Config value: 'markdown_extensions'. Error: Failed loading extension 'foo' from 'foo', 'markdown.extensions.foo' or 'mdx_foo'

Aborted with 1 Configuration Errors!

The final part at the end of the message (after Error: ) is directly from Markdown's error message. We don't tell the user to "install" the extension because we don't know if the extension isn't installed or if they spelled it wrong. The important thing is that it's clear that the problem is related to the markdown_extensions config value foo. The user now understands that they need to work out why the Markdown extension foo does't work. Connecting the error to the markdown_extensions config would not have been possible with option 1, but we get it for free with option 3.

waylan added a commit to waylan/mkdocs that referenced this issue Apr 6, 2018
Fixes mkdocs#782. Note that we mock Markdown in the tests to ensure those
tests are not using Markdown to validate the extension names. We don't
mock Markdown in the tests which we do want Markdown to validate the
extension names.
waylan added a commit to waylan/mkdocs that referenced this issue Apr 6, 2018
Fixes mkdocs#782. Note that we mock Markdown in the tests to ensure those
tests are not using Markdown to validate the extension names. We don't
mock Markdown in the tests which we do want Markdown to validate the
extension names.
waylan added a commit to waylan/mkdocs that referenced this issue Apr 6, 2018
Fixes mkdocs#782. Note that we mock Markdown in the tests to ensure those
tests are not using Markdown to validate the extension names. We don't
mock Markdown in the tests which we do want Markdown to validate the
extension names.
waylan added a commit to waylan/mkdocs that referenced this issue Apr 6, 2018
Fixes mkdocs#782. Note that we mock Markdown in the tests to ensure those
tests are not using Markdown to validate the extension names. We don't
mock Markdown in the tests which we do want Markdown to validate the
extension names.

Also ensure project-min has all relevant extensions.
@waylan waylan closed this in #1459 Apr 6, 2018
waylan added a commit that referenced this issue Apr 6, 2018
Fixes #782. Note that we mock Markdown in the tests to ensure those
tests are not using Markdown to validate the extension names. We don't
mock Markdown in the tests which we do want Markdown to validate the
extension names.

Also ensure project-min has all relevant extensions.
@samoclay
Copy link

@samoclay samoclay commented Jul 31, 2020

INFO    -  Building documentation... 
ERROR   -  Config value: 'markdown_extensions'. Error: Failed loading extension "lightgallery". 

Aborted with 1 Configuration Errors!

I keep getting this but no idea how to resolve it, am i missing something?

@waylan
Copy link
Member

@waylan waylan commented Jul 31, 2020

@samoclay according to the error, lightgallery is not a valid name of any Markdown extensions you have installed. Personally, I'm not familiar with an extension of that name so I can't be sure that you spelled it correctly. I would suggest checking the documentation of the extension. Also, are you sure the extension is installed in the same Python instance as MkDocs?

@samoclay
Copy link

@samoclay samoclay commented Aug 3, 2020

@waylan i have now removed the lightgallery from my mkdocs.yml and tried to rebuild the docs.

  notes git:(test) ✗ mkdocs serve
INFO    -  Building documentation... 
ERROR   -  Config value: 'markdown_extensions'. Error: Failed loading extension "lightgallery". 

Aborted with 1 Configuration Errors!
➜  notes git:(test) ✗ mkdocs serve
INFO    -  Building documentation... 
Traceback (most recent call last):
  File "/Users/sam/.pyenv/versions/3.7.0/bin/mkdocs", line 8, in <module>
    sys.exit(cli())
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/mkdocs/__main__.py", line 136, in serve_command
    **kwargs
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/mkdocs/commands/serve.py", line 141, in serve
    config = builder()
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/mkdocs/commands/serve.py", line 129, in builder
    **kwargs
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/mkdocs/config/base.py", line 197, in load_config
    errors, warnings = cfg.validate()
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/mkdocs/config/base.py", line 115, in validate
    post_failed, post_warnings = self._post_validate()
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/mkdocs/config/base.py", line 95, in _post_validate
    config_option.post_validation(self, key_name=key)
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/mkdocs/config/config_options.py", line 469, in post_validation
    config[key_name] = theme.Theme(**theme_config)
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/mkdocs/theme.py", line 45, in __init__
    self._load_theme_config(name)
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/mkdocs/theme.py", line 75, in _load_theme_config
    theme_dir = utils.get_theme_dir(name)
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/mkdocs/utils/__init__.py", line 297, in get_theme_dir
    return os.path.dirname(os.path.abspath(theme.load().__file__))
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2460, in load
    self.require(*args, **kwargs)
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2483, in require
    items = working_set.resolve(reqs, env, installer, extras=self.extras)
  File "/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages/pkg_resources/__init__.py", line 790, in resolve
    raise VersionConflict(dist, req).with_context(dependent_req)
pkg_resources.VersionConflict: (mkdocs-macros-plugin 0.4.9 (/Users/sam/.pyenv/versions/3.7.0/lib/python3.7/site-packages), Requirement.parse('mkdocs-macros-plugin~=0.3.3'))

I have a feeling might be something to do with how my mac uses python

@waylan
Copy link
Member

@waylan waylan commented Aug 3, 2020

@samoclay I suspect you are correct. If you run the command mkdocs --version, in addition to the MkDocs version, it will report which Python instance on your system it is associated with. Before running MkDocs you will need to ensure that all dependencies (Markdown extensions and MkDocs plugins) are installed on the same instance.

Something you can do to check that is to run pip --version which will report the same info. If pip is associated with a different Python instance, then it won't install packages in a way that MkDocs can find them. You may also try which python to see the full path of the executable that gets called when you run the python command.

I see that your files appear to be under a .pyenv directory. Presumably, MkDocs is installed in a Python virtual environment. You may need to active that environment before running pip and or Python.

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

Successfully merging a pull request may close this issue.

None yet
5 participants