Home > database >  Python try / except does not seem to work with KeyError
Python try / except does not seem to work with KeyError

Time:05-30

Although I've used try/except clauses hundreds of times, I have never seen behavior like this before and I am baffled right now. May I know what am I missing please?

import pandas as pd
import os


season_ep = {}
for season in range(1, 16):
    for ind, row in pd.read_html('https://thetvdb.com/series/curious-george/seasons/official/%d' % season)[0].iterrows():
        season_ep[row['Name']] = row['Unnamed: 0']

errors = []
for root, dirs, files in os.walk("/run/user/1000/gvfs/smb-share:server=nas.local,share=media/TV Shows/Curious George", topdown=False):
    for name in files:
        try:
            to_print = season_ep[name.split('-')[-1][:-4]]
            print(to_print)
        except KeyError:
            errors.append(os.path.join(dirs, name))

for e in errors:
    print('ERROR: %s' % e)

basically, I'm searching for the key 'Old McGeorgie Had a Farm' in the dictionary season_ep which returns a KeyError, but I don't understand why I'm receiving the following error. I would expect the except part to recognize the KeyError and take over, allowing the code to execute fully.

Traceback (most recent call last):
  File "/home/jthom/PycharmProjects/TVDB_ID/main.py", line 14, in <module>
    to_print = season_ep[name.split('-')[-1][:-4]]
KeyError: 'Old McGeorgie Had a Farm'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/lib/python3.10/code.py", line 90, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
  File "/snap/pycharm-community/278/plugins/python-ce/helpers/pydev/_pydev_bundle/pydev_umd.py", line 198, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "/snap/pycharm-community/278/plugins/python-ce/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents "\n", file, 'exec'), glob, loc)
  File "/home/jthom/PycharmProjects/TVDB_ID/main.py", line 17, in <module>
    errors.append(os.path.join(dirs, name))
  File "/usr/lib/python3.10/posixpath.py", line 76, in join
    a = os.fspath(a)
TypeError: expected str, bytes or os.PathLike object, not list

I'm running Python 3.10.4 on Ubuntu 22.04. Thanks for the help!

CodePudding user response:

If you look carefully at the stack trace you will see this snippet: During handling of the above exception, another exception occurred. This is telling you that the above KeyError was caught, but another exception was raised in the execpt block.

The simplest way to get around this would be to add a nested try-except:

        try:
            to_print = season_ep[name.split('-')[-1][:-4]]
            print(to_print)
        except KeyError:
            try:
                errors.append(os.path.join(dirs, name))
            except TypeError:
                # handle this error somehow
                pass

The root of your issue here is that you are passing a list to os.path.join expecting a str, bytes or os.PathLike object, not list. My guess is you want to join the root value rather than dirs. You can see something similar in an example for the docs for os.walk:

# Delete everything reachable from the directory named in "top",
# assuming there are no symbolic links.
# CAUTION:  This is dangerous!  For example, if top == '/', it
# could delete all your disk files.
import os
for root, dirs, files in os.walk(top, topdown=False):
    for name in files:
        os.remove(os.path.join(root, name))
    for name in dirs:
        os.rmdir(os.path.join(root, name))

All in all your path joining code should look like this:

                errors.append(os.path.join(root, name))

CodePudding user response:

If you need to collect a list of error locations, you only need to append the path name root and filename name

    try:
        to_print = season_ep[name.split('-')[-1][:-4]]
        print(to_print)
    except KeyError:
        #errors.append(os.path.join(dirs, name))
        errors.append(os.path.join(root, name))
  • Related