简体   繁体   中英

python 2.x:Conditionally Catching Exceptions (Ignore gracefully cleanup if the file is missing)

I am having a script which cleanups the logs older than 14 days at a shared location. Now this script can run at same time from different host. In a particular situation if two or more hosts try to cleanup same file, only one will succeed and all other gives error "No such file or directory". How can I update the code to Ignore gracefully cleanup if the file suddenly goes missing. Below is part of code which is performing the cleanup. count tracks the number of files deleted.

if os.stat(filename).st_mtime < current_time - 14 * 86400:
    try:
       os.remove(filename)
       count += 1
    except:
       logger.warning("Not able to delete the file %s" % filename)

One way is to "pass" the exception if file dont exist but continue to log warning if you are not able to delete the file. How to include this condition.

As @Mark suggests you could check beforehand if the file exists and then delete it but there is still a potential race condition in such an approach. It can occur between script's instances after os.stat and before os.remove . Moving all of the code raising errors to try / except should do the job. However, as I understand there is a problem with logging a truthful message. Additional flag attempted_delete should help with that:

attempted_delete = False
try:
    if os.stat(filename).st_mtime < current_time - 14 * 86400:
         os.remove(filename)
         count += 1
         attempted_delete = True
except:
     if attempted_delete:
         logger.warning("Not able to delete the file %s" % filename)

An except clause with no exception (type) list is a catch-all: easy to setup but hard to use. Here you should specifically catch (and ignore) a FileNotFoundError and log any other exception:

try:
   if os.stat(filename).st_mtime < current_time - 14 * 86400:
      os.remove(filename)
      count += 1
except FileNotFoundError:
   pass  # file has already been deleted: all is fine
except:
   logger.warning("Not able to delete the file %s" % filename)

Above was for Python 3, as you use Python 2, you can only check for OSError and then control its errno attribute:

try:
   if os.stat(filename).st_mtime < current_time - 14 * 86400:
      os.remove(filename)
      count += 1
except OSError as e:
   if e.errno != errno.ENOENT:
      # do not log if file has already been deleted
      logger.warning("Not able to delete the file %s" % filename)
except:
   logger.warning("Not able to delete the file %s" % filename)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM