The Hidden Bug Behind Missing Files in Python

Sagnik DevSagnik Dev
3 min read

So, I learnt about exception handling using try, except, and finally and was practicing it, when I ran into a bug that at first made no sense to me. To be precise I was curious to see whether not using finally affects the execution of my program or not. I was told that finally is like a ‘clean up code’ which essentially closes the file by any means and disconnects it from the database, etc. Knowing(somewhat) that, I wrote the code:

I was expecting some error after executing the program, and I did get one, however it was clear that the error did not arise due to absence of finally. The error said:

This seemed like the error turned up because of the ‘absence’ of the file, which was weird as the exception was meant to be handled. Still to confirm that the error was not due to some other syntaxial error, I rewrote the code as it was meant to, i.e. using finally. However, it showed the same issue as I had expected.

What Happened?

Hence it was confusing. My logic was fairly simple:

  • The code will try to open the file.

  • If it doesn't exist → raise FileNotFoundError.

  • Catch the error and print the message.

  • Move to finally, and things are done.

But on digging, I found that what actually was happening is that when Python tries to run

and the file doesn’t exist:

  • It raises a FileNotFoundError.

  • The except block prints "File not found.".

  • But then the finally block runs → and it says:

    And Python says that ‘file’ is not defined, because:

  • file = open(...) never succeeded

  • So, the variable file was never created

  • And now I’m calling .close() on something that doesn't exist

So, the problem was not FileNotFoundError handling - as that part works perfectly. The problem was that:

  • I was trying to use a variable (file) that never got assigned, because open() failed.

  • So, Python throws a second error: UnboundLocalError.

The Fix?

After some googling and experimenting, I found two good ways to solve this:

  1. Using another try-except inside finally:

    Here through the nested try-except, we are checking if file exists before closing it. As a result, even if the file wasn't opened, Python doesn't crash.

  2. Using with open(...):

    Much simpler. Here with automatically closes the file when the block ends, even if an error occurs.

What I Learned?

  1. Catching one error doesn't prevent other errors.

  2. Variables are needed to be assigned before being used — or Python will complain.

  3. with open(...) is definitely something I’ll use more often going forward.

To sum up, debugging this was worth delving into. If you’re just getting into Python, I hope this helps you avoid the same trap. If you have tips, corrections, or ideas — I’d love to hear them!

0
Subscribe to my newsletter

Read articles from Sagnik Dev directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sagnik Dev
Sagnik Dev