I have the below code:
version A
try:
file = open(local_copy, "wt")
n = file.write(str(soup))
logging.debug(f'\t{local_copy} saved. {n} lines saved.')
except IOError as e:
logging.error(traceback.print_exc())
finally:
file.close()
version B
try:
with open(local_copy, "wt") as file:
n = file.write(str(soup))
logging.debug(f'\t{local_copy} saved. {n} lines saved.')
except IOError as e:
logging.error(traceback.print_exc())
finally:
None
Both are failing with [Errno 9] Bad file descriptor. It is caugt by exception handler higher up the stack.
Now, I am passing True
(boolean) as local_copy's value. I know it will fail, my goal here however is to handle the error properly.
I ended up doing the below, but do not find this the best solution. I'd like to know why the initial try...catch block cannot catch this. Is there a different, better way to handle IOErrors
?
if not isinstance(local_copy, str):
logging.error(f"Cannot store localcopy of the file")
logging.error(f'"local_copy" variable holds a value of an incorrect type: {type(local_copy)} (required str).')
else:
try:
file = open(local_copy, "wt")
n = file.write(str(soup))
logging.debug(f'\t{local_copy} saved. {n} lines saved.')
# with open(local_copy, "wt") as file:
# n = file.write(str(soup))
#
# logging.debug(f'\t{local_copy} saved. {n} lines saved.')
except IOError as e:
logging.error(traceback.print_exc())
finally:
file.close()
#None
OSError also does not catch anything, as well as Exception.
Standalone example:
import io
local_copy = True
soup = "Great soup"
try:
file = open(local_copy, "wt")
n = file.write(str(soup))
print(f'\t{local_copy} saved. {n} lines saved.')
except OSError as e:
print("we got the error")
finally:
file.close()
print ("Done")
Output:
$ python3 test.py
True saved. 10 lines saved.
Great soupTraceback (most recent call last):
File "test.py", line 18, in <module>
print ("Done")
OSError: [Errno 9] Bad file descriptor
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
OSError: [Errno 9] Bad file descriptor
Why am I getting exception ignored? Also, why the content of soup is being send to stdout?
Your code:
local_copy = True
....
file = open(local_copy, "wt")
creates a file object from the value True
which is identical to integer 1
, which represents a file descriptor for the standard output, i.e. the channel where all prints emit the messages by default.
(Usually open
is used with a filename - I guess you did not intend to write to the standard output.)
When you close that file, you close your standard output. The first print after that point will fail:
print("Done")
because it cannot print to closed output. This is the cause for the exception reported.