Reputation:
How would I return the error received during a function call back to main?
I've got something simple such as:
def check(file):
if not os.path.exists(file): # returns false by itself, but I want error
return -1
When called, it just returns to the calling .py
and the program ends. But I am trying to return what happened (i.e. the file does not exist). Is raising an exception more appropriate?
Upvotes: 0
Views: 837
Reputation: 16007
(As an alternative to my previous answer.)
Another more correct way to do the check()
if you want to explicitly check before doing anything else - use os.stat()
which doesn't actually open the file:
import os
def check(file):
try:
os.stat(file)
# continue doing something here or
# return to the function which wants to open file
except FileNotFoundError as e:
# log error, print error, or.. etc.
raise e # and then re-raise it
Result of this version is:
>>> check('xyz')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in check
File "<stdin>", line 3, in check
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'xyz'
>>>
Note that the error is a bit different here vs the prev: [Errno 2] No such file or directory: 'xyz'
Upvotes: 0
Reputation: 16007
If you do want to raise an exception instead of returning -1
when the file doesn't exist, you could skip the check()
and go directly to open()
or whatever you actually want to do with the file.
The correct way to actually raise the exception is to let it get raised. So do:
def check_and_open(file):
# raises FileNotFoundError automatically
with open('xyz', 'r') as fp:
fp.readlnes() # or whatever
And if you do want to explicitly check before you open, this will raise the actual error object:
def check(file):
try:
with open(file, 'r') as fp:
# continue doing something with `fp` here or
# return `fp` to the function which wants to open file
pass
except FileNotFoundError as e:
# log error, print error, or.. etc.
raise e # and then re-raise it
Result of this version is:
>>> check('xyz')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 9, in check
File "<stdin>", line 3, in check
FileNotFoundError: [Errno 2] No such file or directory: 'xyz'
>>>
Also, note that just doing raise FileNotFoundError(file)
, like in another answer provided, breaks how FileNotFoundError
actually raises:
Raising explicitly (the filename gets considered as the err message):
>>> raise FileNotFoundError('xyz')
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
FileNotFoundError: xyz
>>>
How it's actually raised by Python:
>>> fp = open('xyz', 'r')
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'xyz'
>>>
>>> # or with `with`:
... with open('xyz', 'r') as fp:
... fp.readlnes()
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'xyz'
>>>
Upvotes: 1
Reputation: 1844
You could raise
an exception (FileNotFoundError
is used in built-in libraries), although if you'll try to use non-existent file you'll get FileNotFoundError
exception raised by default.
Then, when using this function, handle your exception:
import os
def check(file):
if not os.path.exists(file):
raise FileNotFoundError(file)
if __name__ == '__main__':
try:
check(os.path.join('foo', 'bar'))
except FileNotFoundError:
print('File was not found')
Upvotes: 0