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

Increase verbosity of "Unable to correctly parse dotenv file" error when violating IncorrectNameViolation #30

Open
Levivb opened this issue Jan 12, 2019 · 4 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@Levivb
Copy link

Levivb commented Jan 12, 2019

Bug report

What's wrong

The linter will return a rather not-helpful message "Unable to correctly parse dotenv file" when the dotenv file contains invalid characters in the name. For example:

;INCORRENT_COMMENT=disabled
SOME@KEY=incorrect

How is that should be

The linter should return something like:

.env:22 101 Found incorrect name: ;INCORRENT_COMMENT
.env:23 101 Found incorrect name: SOME@KEY

System information

Linux homestead 4.15.0-32-generic #35-Ubuntu SMP Fri Aug 10 17:58:07 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

flake8 information

n/a

pip information

not relevant

@sobolevn
Copy link
Member

@Levivb hm, thanks for the feedback.

However, I guess raising IncorrectNameViolation instead is not a good option.
I would prefer just to raise something like this: Unable to correctly parse dotenv file, line: ";INCORRENT_COMMENT=disabled"

What do you think?

@Levivb
Copy link
Author

Levivb commented Jan 12, 2019

That would be fine as well.
From a user perspective it's still an invalid key, but I reckon that would cause conflicting behaviour since other violations are hard to check when the file can't be processed correctly in the first place.

In my case I had to remove all lines from the file and add them in batches until the error pops up.
Your proposed solution would prevent that, so it sounds like a viable solution :)

@sobolevn
Copy link
Member

sobolevn commented Jan 12, 2019

@Levivb are you interested in giving this a try with a PR? 🙂

@Levivb
Copy link
Author

Levivb commented Jan 12, 2019

I'm afraid my python knowledge is not sufficient enough to get this done in a reasonable amount of time.

I checked the source code and tried a few things. But since I even have to google how to get the human readable message out of an exception... or even how to get a named exception in the first place (except ParsingError as pe: vs except ParsingError), I'll write some pseudo code for you to do with as you wish.

.env file contents:
KEY_0="KEY@2=sec(o)nd with error"
KEY_1=first
KEY@2=sec(o)nd with error
KEY_3=third
KEY_4=fourth

# In checker.py in def _prepare_fst:
try:
    return self._parser.parse(file_contents)
except ParsingError as pe:
   #pe = '@2=sec(o)nd\nKEY_3=third\nKEY_4=fourth\n'
   #get first violating line
    violating_line = str(pe).split('\n')[0]
   #violating_line == @2=sec(o)nd

#there are two options here:
1.
file_contents_array = file_contents.split('\n')
for each line in file_contents_array:
  check if line corresponds to regex ^\w* regex_escape(violating_line) $
    # explanation: (ignore the spaces in the regex. they are only for readability here)
    # the line should start ^
    #the exception doesn't show the first part of the violating line
    #  so our regex should take that into account by allowing \w character group before the violating character
   # this will prevent false positives like: KEY_0="KEY@2=sec(o)nd with error"
   #
   # the violating line should be escaped for the regex so any regex specific characters aren't parsed as such. In this case `sec(o)nd` would try to match `second` where the `o` would be in a match group. When escaping, it would match exactly `sec(o)nd`
   # the line should end $
   
   if regex matches, print the line with message it violates and break loop

2.
  find the index of the substring `(^|\\n) \w* regex_escape(violating_line) ($|\\n)`
  # ignore the spaces in the regex. they are only for readability here
  # explanation: find start of string or newline character followed by any alphanumeric character. Followed by the violating string, followed by the end of the line or the next newline from the .env file
  # normally you'd use \b as word boundary, but since the newlines in the file_contents are actually truly the \ and n character, this won't work

  create a substring from the file_contents from the found index to the nearest \n or \b and print that substring

    return None

@sobolevn sobolevn added enhancement New feature or request help wanted Extra attention is needed labels Jan 15, 2019
@sobolevn sobolevn mentioned this issue Jan 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants