4

When a program receives a filename argument that does not exist, or is not a directory, I want to raise an error. But what error is considered best practice?

I understand that ValueError is often used to signal invalid arguments (and I've seen several questions about it). I also understand that, especially after the reorganization of exceptions in Python 3.3 (PEP 3151), OSError is the catch-all category for problems related to interaction with the system.

So, I have a program that expects a filename argument. If the name supplied by the caller does not exist, or exists but is a directory, what error should I raise? It's an incorrect argument so it seems that ValueError applies; but if I try to read from it as a file, I will get an OSError-- so shouldn't this be returned for consistency?

Community
  • 1
  • 1
alexis
  • 48,685
  • 16
  • 101
  • 161
  • 1
    Do you need to raise *anything* at this point? If it does matter whether the file exists or not, there's probably going to be another exception raised down the road anyway. In other words: what's your use case for raising? – Thomas Orozco Apr 29 '15 at 20:58
  • If the exception is not meant to be caught, it's just a question of aesthetics; but I am after the principle behind this, so let's assume that this is a long-running program and the error will get caught and the module will get called with new arguments (e.g., interactively). – alexis Apr 29 '15 at 21:08
  • 1
    This is a bit of an anti-pattern in Python: you're supposed to ask for forgiveness, not permission. So, if you're not going to do anything about the error, just ignore it, let whatever is going to crash crash, and let the resulting exception bubble up to the caller. I'd add an exception (no pun intended) to this rule if you're writing a library, in which case you might want your own exception hierarchy so that users can catch errors coming from your lib (e.g. like `requests` has `HTTPError`). – Thomas Orozco Apr 29 '15 at 21:09
  • EAFP ... LBYL are just two competing schools of thought neither is an antipattern ... although in general python favors EAFP – Joran Beasley Apr 29 '15 at 21:32

1 Answers1

2

does it really matter?(I assume you are not catching this exception and it is purely for informational purposes of an individual looking at the terminal output) none of that will be seen by the operating system as such I would just

raise Exception("Invalid Arguments, expected a file that exists not %r"%(filename))

or just let it fail when it tries to open the file naturally even

Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
  • 1
    If I let it try to open the file naturally, I _will_ get an OSError... hence this question. I prefer the look-before-you-leap approach, but I have a feeling the exception should not depend on my coding style. – alexis Apr 29 '15 at 21:04
  • so your asking if you should catch it and raise a Different OS error? or if you should do `if not os.exists(fname): raise OSError("File Doesnt exist")` which is almost identical to `fh = open(some_file)` except you wont get a filehandle back in the event it does exist – Joran Beasley Apr 29 '15 at 21:13
  • Well, if I do raise OSError the result is similar, but with ValueError it is not. That's the motivation for considering OSError, as I wrote. – alexis Apr 29 '15 at 23:10
  • in both cases the program exits with a non-zero exit code ... the OS has no idea about any of these error types ... all you want to do is express to the user what the problem is ... the only time you need to worry about this is if you plan on catching the error, in order to distinguish different logic depending on the errortype – Joran Beasley Apr 29 '15 at 23:19
  • Thanks but I know, I mentioned this in a comment under the question. My motivation for asking the question is largely conceptual, but let's assume that the error _will_ be caught, otherwise the question is indeed pointless. But I'm not looking for "it's pointless" as an answer. – alexis Apr 29 '15 at 23:23
  • 1
    well if you are going to catch it I would raise an OSError or even a custom FileNotFound Exception ... but if thats the case why wouldnt you let the normal OSError bubble up and be caught at the level your 2nd error would be caught at ... Im not being a smart ass(or intentionally difficult) I swear, these are things you should think about though – Joran Beasley Apr 29 '15 at 23:25
  • One reason I might want to raise the error myself is if I should in fact raise ValueError. From reading the PEPs it seems that the most important criterion for choosing (and designing) exceptions is which collections of them one might want to catch. I'd catch it together with other argument-related errors (hence: ValueError), but I wrote this question so I can benefit from collective experience... – alexis Apr 30 '15 at 13:44