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

Fixes 4893 - error handling for malformed configurations #5026

Closed
wants to merge 4 commits into from
Closed

Fixes 4893 - error handling for malformed configurations #5026

wants to merge 4 commits into from

Conversation

fishd
Copy link

@fishd fishd commented Feb 14, 2018

This fixes #4893 . In the event that a pip conf has malformed headers, it will handle the error and raise a specific message. Previously, pip would exit with a traceback.

Two things I'm uncertain about:

  1. This is a very specific error case, modeled after the original problem referenced in the ticket. Would it be better to handle more generic ConfigParser errors, or perhaps to add additional excepts for other parser exceptions?
  2. Not sure if I put the test in the right location!

@fishd
Copy link
Author

fishd commented Feb 14, 2018

Hmm, I'm actually stumped about the build failure. It looks like one is a timeout and one is a mypy error.

The mypy error appears to relate to my first question as to which exceptions we want to be handling here:
src/pip/_internal/configuration.py:295: error: Exception type must be derived from BaseException

So maybe catching MissingSectionHeader is not appropriate? However, I'm still not sure why it would get flagged.

Copy link
Member

@pradyunsg pradyunsg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, this review has been sitting idle for a bit. Sorry for the wait. :(

@@ -46,6 +46,17 @@ def test_environment_config_loading(self):
assert self.configuration.get_value("test.hello") == "4", \
self.configuration._config

def test_environment_config_errors_if_malformed(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel a better idea would be to create a new class called TestConfigurationLoadingErrors(ConfigurationMixin) in the same file and move this test there.

I imagine I'll add more tests to such a class in the future.

news/4893.bugfix Outdated
@@ -0,0 +1 @@
Add handling for configparser errors when conf is malformed.
Copy link
Member

@pradyunsg pradyunsg Feb 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Malformed configuration files now show helpful error messages, instead of tracebacks.

@@ -292,6 +292,13 @@ def _construct_parser(self, fname):
"Configuration file contains invalid %s characters.\n"
"Please fix your configuration, located at %s\n"
) % (locale.getpreferredencoding(False), fname))
except configparser.MissingSectionHeaderError:
Copy link
Member

@pradyunsg pradyunsg Feb 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error here seems to be caused by an incorrect declaration in typeshed.

For now, you can add a # type: ignore to the end of this line and a comment above that links to python/typeshed#1883.

"ERROR: "
"Configuration file headers cannot be parsed. \n"
"Please fix the section formatting of the "
"configuration located at %s.\n" % fname
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the "." at the end -- that way it is easier to just copy the entire path by selecting everything after "at".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This message should mention the lineno from the error raised. That would be helpful while trying to locate the error.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thought, we should also add a handler after this for ParsingError since they may be raised for other reasons.


with pytest.raises(ConfigurationError):
self.configuration.load()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should check for the word "malformed" (or something similar), the line number and the file path are mentioned in the error message.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean that it should check for all three of those things in the error message string? Presumably inside of the with block?

Copy link
Member

@pradyunsg pradyunsg May 31, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with pytest.raises(ConfigurationError) as err:
    self.configuration.load()

assert "malformed" in str(err)
assert lineno in str(err)
assert filepath in str(err)

@pradyunsg
Copy link
Member

About the mypy error, it was a bug in typeshed, fixed it in python/typeshed@b6bd582. I noted the workaround above. :)

@pradyunsg pradyunsg added this to the 10.0 milestone Mar 4, 2018
@pradyunsg pradyunsg added the type: enhancement Improvements to functionality label Mar 4, 2018
@pfmoore
Copy link
Member

pfmoore commented Mar 26, 2018

@fishd Are you likely to have time to resolve this in the coming week? Pip 10 beta will be released at the weekend, and if this PR can't be merged by then, I'd prefer to defer it until post pip 10 final.

@fishd
Copy link
Author

fishd commented Mar 26, 2018

Yes, sorry that I sat on it for so long! I can get it resolved in the next few days.

@pradyunsg

This comment has been minimized.

@pradyunsg pradyunsg mentioned this pull request Mar 30, 2018
@pfmoore
Copy link
Member

pfmoore commented Mar 30, 2018

Sorry, but this is going to have to wait until post-10.0 now.

@pradyunsg
Copy link
Member

Fine by me.

@dstufft dstufft modified the milestones: 10.0, 10.1 Mar 31, 2018
@pradyunsg
Copy link
Member

Ping @fishd

@pradyunsg pradyunsg added the S: awaiting response Waiting for a response/more information label May 11, 2018
@fishd
Copy link
Author

fishd commented May 30, 2018

Hi, I am not dead. Thank you for your patience.

I have some clarifying questions. I'll attempt to add those as inline comments...

raise ConfigurationError(
"ERROR: "
"Configuration file cannot be parsed. \n"
"%s\n" % e.message
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is killing the CI build (no "message" attribute), but I can't seem to reproduce it. I suspect something about what I'm doing is bad practice...?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just do str(e) here. It'll result in the same output: https://github.com/python/cpython/blob/3.6/Lib/configparser.py#L174

@pradyunsg
Copy link
Member

@fishd You seem to have rebased incorrectly.

@fishd
Copy link
Author

fishd commented Jun 8, 2018

Whoops. I feel like that looks different than it did on my local branch...I'll investigate.

Remove period for easier path copying

Move config parsing error to new class

4893 - Add line number, add handling for generic ParsingErrors.

Remove whitespace.

Convert parsing error to string

PEP8 - reformat line break
Copy link
Member

@pradyunsg pradyunsg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Older inline comments still apply.

@pradyunsg
Copy link
Member

@fishd Do you have the time to make the requested changes? If not, I'll be happy to take this from here -- I'd like this to be a part of the next release.

@pradyunsg
Copy link
Member

Pushing this down the road to the next release since I don't think this'd happen in time for 18.0.

@pradyunsg pradyunsg modified the milestones: 18.0, 18.1 Jul 15, 2018
@pradyunsg pradyunsg self-assigned this Jul 15, 2018
Adds more checks and skips creating a new class.
pradyunsg
pradyunsg previously approved these changes Aug 13, 2018
@pradyunsg
Copy link
Member

I'll take this up and redo this PR, reusing messages from the stdlib configparser.

@pradyunsg pradyunsg dismissed their stale review September 18, 2018 13:51

As commented.

@pradyunsg pradyunsg closed this Sep 18, 2018
@pradyunsg pradyunsg removed this from the 18.1 milestone Sep 18, 2018
@lock
Copy link

lock bot commented Jun 1, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot added the auto-locked Outdated issues that have been locked by automation label Jun 1, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Jun 1, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
auto-locked Outdated issues that have been locked by automation S: awaiting response Waiting for a response/more information type: enhancement Improvements to functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Invalid Configuration File causes a traceback + crash
4 participants