# Buggy code
def getDirsMtimes(self, dirs, yieldcall=None):
    list = {}

    for folder in dirs:
        folder = os.path.expanduser(folder.replace("//", "/"))

        if self.hiddenCheck({"dir": folder}):
            continue

        try:
            mtime = os.path.getmtime(folder)
        except OSError as errtuple:
            message = _("Scanning Directory Error: %(error)s Path: %(path)s") % {
                "error": errtuple,
                "path": folder,
            }
            print(str(message))
            self.logMessage(message)
            continue

        list[folder] = mtime

        try:
            for entry in os.scandir(folder):
                if entry.is_dir():
                    path = os.path.join(folder, entry.path.split("/")[-1])

                    try:
                        mtime = os.path.getmtime(path)
                    except OSError as errtuple:
                        islink = False
                        try:
                            islink = os.path.islink(path)
                        except OSError as errtuple2:
                            print(errtuple2)

                        if islink:
                            message = _(
                                'Scanning Error: Broken link to directory: "%(link)s" from Path: "%(path)s". Repair or remove this link.'
                            ) % {"link": os.readlink(path), "path": path}
                        else:
                            message = _("Scanning Error: %(error)s Path: %(path)s") % {
                                "error": errtuple,
                                "path": path,
                            }

                        print(str(message))
                        self.logMessage(message)
                        continue

                    list[path] = mtime
                    dircontents = self.getDirsMtimes([path])
                    for k in dircontents:
                        list[k] = dircontents[k]

                if yieldcall is not None:
                    yieldcall()
        except OSError as errtuple:
            message = _("Scanning Directory Error: %(error)s Path: %(path)s") % {
                "error": errtuple,
                "path": folder,
            }
            print(str(message))
            self.logMessage(message)
            continue

    return list


# Traceback (KeyError)
Traceback (most recent call last):
File "/usr/local/lib/python3.7/shelve.py", line 111, in __getitem__
value = self.cache[key]
KeyError: 'Klassiek\\Jean Sibelius\\Two Serenades for Violin and Orchestra, Op.69'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/pynicotine/gtkgui/frame.py", line 2039, in _RescanFinished
self.np.shares.sendNumSharedFoldersFiles()
File "/usr/local/lib/python3.7/site-packages/pynicotine/shares.py", line 105, in sendNumSharedFoldersFiles
sharedfiles = sum([len(x) for x in list(conf["transfers"][shared_db].values())])
File "/usr/local/lib/python3.7/_collections_abc.py", line 762, in __iter__
yield self._mapping[key]
File "/usr/local/lib/python3.7/shelve.py", line 113, in __getitem__
f = BytesIO(self.dict[key.encode(self.keyencoding)])
File "/usr/local/lib/python3.7/shelve.py", line 70, in closed
raise ValueError('invalid operation on closed shelf')
ValueError: invalid operation on closed shelf

# Fixed code
def getDirsMtimes(self, dirs, yieldcall=None):
    list = {}

    for folder in dirs:
        try:
            if self.hiddenCheck({"dir": folder}):
                continue

            mtime = os.path.getmtime(folder)
            list[folder] = mtime

            for entry in os.scandir(folder):
                if entry.is_dir():
                    path = entry.path

                    try:
                        mtime = entry.stat().st_mtime
                    except OSError as errtuple:
                        message = _("Scanning Error: %(error)s Path: %(path)s") % {
                            "error": errtuple,
                            "path": path,
                        }

                        print(str(message))
                        self.logMessage(message)
                        continue

                    list[path] = mtime
                    dircontents = self.getDirsMtimes([path])
                    for k in dircontents:
                        list[k] = dircontents[k]

                if yieldcall is not None:
                    yieldcall()
        except OSError as errtuple:
            message = _("Scanning Directory Error: %(error)s Path: %(path)s") % {
                "error": errtuple,
                "path": folder,
            }
            print(str(message))
            self.logMessage(message)
            continue

    return list