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

throw nice error if directory doesn't exist #203

Merged
merged 13 commits into from Sep 13, 2018

Conversation

harsham4026
Copy link
Contributor

@MSeal this addresses the issue of Nicer error when output directory doesn't exist #201
Please review the PR and let me know for any changes. At present I added the exception throwing for local file system. Please let me know if I need to do the same for others as well

@codecov
Copy link

codecov bot commented Sep 12, 2018

Codecov Report

Merging #203 into master will increase coverage by 0.12%.
The diff coverage is 100%.

@@            Coverage Diff            @@
##           master    #203      +/-   ##
=========================================
+ Coverage   77.38%   77.5%   +0.12%     
=========================================
  Files          11      11              
  Lines        1110    1116       +6     
=========================================
+ Hits          859     865       +6     
  Misses        251     251

@harsham4026
Copy link
Contributor Author

harsham4026 commented Sep 12, 2018

@MSeal please review

Could you please consider merging the changes?

@@ -88,6 +88,12 @@ def listdir(cls, path):

@classmethod
def write(cls, buf, path):
dir = (path.split("/"))[:-1]
Copy link
Member

Choose a reason for hiding this comment

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

I am not quite sure what the next few lines do but I think they try and find the directory name in the path. I'd recommend using https://docs.python.org/3/library/os.path.html#os.path.dirname or other tools from that module to do this.

By using an existing tool from the standard library you make it easier for others to read your code and we are less likely to have a bug in the code that manipulates the path.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@betatim Sure. Will make the change as you suggested

@@ -13,6 +13,10 @@ class FileExistsError(AwsError):
"""Raised when a File already exists on S3."""


class FileNotFoundError(AwsError):
Copy link
Member

Choose a reason for hiding this comment

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

I think we shouldn't inherit from AwsError here as the exception is only used for local files.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@betatim ok. Can I throw the normal Exception with the message that directory doesn't exists?

Copy link
Member

Choose a reason for hiding this comment

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

@harsham4026 There's already a built-in FileNotFoundError in Python. Let's use that here :)

@betatim
Copy link
Member

betatim commented Sep 12, 2018

Thanks for working on this! I left some feedback.

It would be super nice to add a test to make sure that the correct exception is raised when the directory does not exist and not raised when the directory is missing.

@harsham4026
Copy link
Contributor Author

harsham4026 commented Sep 12, 2018

@betatim Made the changes you suggested using the standard OS library for getting the directory path. And I removed the exception added in AwsError and raising the exception if dir doesn't exist. Can you please request to merge these changes to Master?

@betatim
Copy link
Member

betatim commented Sep 12, 2018

I should have been clearer with my comment about the exception: I would keep the custom exception but I would not have it inherit from AwsException and instead inherit from Exception.

if not dir.endswith("/"):
dir += "/"
if not os.path.exists(dir):
raise Exception('output folder {} doesn\'t exist!'.format(dir))
Copy link
Member

Choose a reason for hiding this comment

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

I'd rewrite this block as:

dir_name = os.path.dirname(path)
if not os.path.exists(dir_name):
    raise NoSuchDirectory("The output folder {} does not exist.".format(dir_name))

and define a NoSuchDirectory exception

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@betatim have you added this NoSuchDirectory exception or shall I add and commit the code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@betatim added the code block and committed.

@harsham4026
Copy link
Contributor Author

@betatim yes I added a custom exception and inherited from Exception instead of AwsException.

Copy link
Member

@MSeal MSeal left a comment

Choose a reason for hiding this comment

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

Thanks for making the contribution! A few minor notes here. As tim mentioned, a quick test would be nice to keep out coverage going up instead of down :)

if not dir.endswith("/"):
dir += "/"
if not os.path.exists(dir):
raise NoSuchDirectory('output folder {} doesn\'t exist.'.format(dir))
Copy link
Member

Choose a reason for hiding this comment

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

Let's still use FileNotFoundError instead of making a new error class, as it's used for missing directories as well.

From Python docs:
| exception FileNotFoundError
| Raised when a file or directory is requested but doesn’t exist. Corresponds to errno ENOENT.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@MSeal used FileNotFoundError for throwing the error if a folder or file doesn't exist but the build is failing because FileNotFoundError is not directly supported in Python 2.7. Could you please let me know if we can proceed this way.

@@ -88,6 +88,11 @@ def listdir(cls, path):

@classmethod
def write(cls, buf, path):
dir = os.path.dirname(path)
if not dir.endswith("/"):
Copy link
Member

Choose a reason for hiding this comment

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

I don't think you need this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@MSeal removed this piece of code

@@ -88,6 +88,11 @@ def listdir(cls, path):

@classmethod
def write(cls, buf, path):
dir = os.path.dirname(path)
Copy link
Member

@MSeal MSeal Sep 12, 2018

Choose a reason for hiding this comment

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

Since dir is a reserved keyword in python let's use a different name here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@MSeal removed the dir and used os.path.dir(path)

@harsham4026
Copy link
Contributor Author

@MSeal made the changes you suggested but the build is failing as FileNotFoundError directly not available to use in Python 2.7
screen shot 1940-06-22 at 12 30 33 am

@harsham4026
Copy link
Contributor Author

harsham4026 commented Sep 12, 2018

@MSeal added the test case to check if it throws error when we give a folder which doesn't exist and it's passed. Please have a look into the following build
https://travis-ci.org/nteract/papermill/builds/427840680?utm_source=github_status&utm_medium=notification
Could you please consider having a review and merging it?

@MSeal
Copy link
Member

MSeal commented Sep 12, 2018

@harsham4026 You can add

try:
    FileNotFoundError
except NameError:
    FileNotFoundError = IOError

in both the iorw.py and the test file to fix the test error for python 2 (this is the recommended pattern as FileNotFoundError is a child of IOError and IOError is what python 2 built-in libraries use for this issue. Sorry I forgot python 2 didn't have this error type when I mentioned it before.

@MSeal
Copy link
Member

MSeal commented Sep 12, 2018

Once that's in place and the tests pass I'll happily hit merge :)

Apologies there that there were a lot of small asks on the PR here.

@harsham4026
Copy link
Contributor Author

@MSeal made the changes as you suggested and now the build is successful :)

@MSeal MSeal merged commit 8d6eeaf into nteract:master Sep 13, 2018
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

Successfully merging this pull request may close these issues.

None yet

3 participants