0

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?

asked Jun 29, 2017 at 14:07
4
  • 1
    Maybe you want to look a bit at How to handle exceptions in Python Commented Jun 29, 2017 at 14:08
  • 2
    This is up to you as the designer of the software. If you want to raise an exception because the file does not exist, then instead of returning -1, raise an exception yourself. Commented Jun 29, 2017 at 14:08
  • "what happened" is that os.path.exists(file) returned False. the calling .py file should be structured to handle this possible return value, or you should be raising an error (which will raise to the calling procedure). Commented Jun 29, 2017 at 14:11
  • 1
    Raising an exception is more explicit and safer than returning some value. With an exception, you'll be sure that either you deal with it, or your code fails immediately. If you return -1, you have to take care to test it everytime you use it, and things can silently go wrong if you forget to do so. Commented Jun 29, 2017 at 14:15

3 Answers 3

1

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'
>>>
answered Jun 29, 2017 at 14:43
Sign up to request clarification or add additional context in comments.

Comments

0

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')
answered Jun 29, 2017 at 14:10

Comments

0

(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'

answered Jun 29, 2017 at 15:08

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.