Courseiva
Exceptions and File I/O →easyMultiple Choice

PCAP Exceptions and File I/O Practice Question

A small web application allows users to download files from a server. The code uses open() without any exception handling. When a user requests a non-existent file, the server crashes with a traceback and returns a 500 Internal Server Error to the client. The team needs to modify the code to handle this situation gracefully: if the file does not exist, the application should return a 404 Not Found response (by calling a function send_404()). The application should not catch unrelated exceptions like KeyboardInterrupt. Which modification is the most appropriate?

⚠ Common exam trap

Python Institute often tests the distinction between catching a specific exception (FileNotFoundError) versus its parent class (OSError), and the trap here is that candidates may choose the broader OSError (Option C) thinking it covers all file-related errors, but that would incorrectly handle permission or other OS errors as 404s.

Answer choices

Why each option matters

Answer the question above first, then reveal the full breakdown to understand why each option is right or wrong.

Correct answer & explanation

✓

Wrap the open() call in a try-except block catching FileNotFoundError, and in the except block call send_404().

It catches the specific exception raised when a file is not found (FileNotFoundError), which is a subclass of OSError. This allows the code to return a 404 response for missing files while not catching unrelated exceptions like KeyboardInterrupt, as required. The except block calls send_404() to handle the missing file gracefully without crashing the server.

Answer analysis

Option-by-option breakdown

For each option: why learners choose it and why it is or isn't the right answer here.

  • ✗

    Wrap the entire request handling in a try-except block catching Exception, and if any exception occurs, call send_500().

    Why it's wrong here

    Wrapping an entire request handler in a catch-all Exception clause converts every unexpected programming error—TypeError, ValueError, KeyError, even bugs in your own code—into a 500 response, concealing the real failure and potentially leaving uncommitted state or partial work. This is over-broad because only genuinely server-side failures should map to send_500(); client-caused conditions like malformed input or a nonexistent file should not be swallowed into that category. It also makes debugging harder because the original traceback is effectively discarded.

  • ✗

    Check if the file exists using os.path.exists before opening, and if not, call send_404().

    Why it's wrong here

    Using os.path.exists before open() is a classic look-before-you-leap pattern that introduces a time-of-check-to-time-of-use race: the file can be removed or renamed between the exists() call and the open() call, so open() can still fail with FileNotFoundError after exists() returned True. Conversely, a path with an unreadable file may return True from exists() because existence and readability differ, causing open() to fail with PermissionError after your pre-check. The Pythonic idiom is to attempt the operation and catch the specific exception, not to pre-verify existence.

  • ✗

    Wrap the open() call in a try-except block catching OSError, and in the except block call send_404().

    Why it's wrong here

    OSError is the base class for an entire family of I/O-related exceptions, including FileNotFoundError, PermissionError, IsADirectoryError, and BlockingIOError. Catching OSError and answering with send_404() therefore assigns the same 'not found' semantics to permission denials, attempts to open a directory, or interrupted system calls—each of which deserves a different status code or another fallback. Only missing files should be reported as 404; catching the parent class hides legitimate operational failures and misleads the client about the true cause.

  • ✓

    Wrap the open() call in a try-except block catching FileNotFoundError, and in the except block call send_404().

    Why this is correct

    FileNotFoundError is a precise subclass of OSError that Python's open() raises when the requested path cannot be found, including cases where a parent directory is missing or the path is a dangling symlink. By catching only this exception, the handler maps the specific 'missing resource' condition to send_404() and lets every other I/O problem—such as PermissionError—propagate or be handled elsewhere. This follows the EAFP (easier to ask forgiveness than permission) idiom and avoids the broader catch-all problems of checking existence beforehand.

About these practice questions

This PCAP question is part of Courseiva's 421-question bank — original exam-style content with full explanations and wrong-answer analysis, never real exam questions or exam dumps. Learn why practice questions differ from exam dumps →

How Courseiva writes practice questions · Editorial policy

JA

Written by Johnson Ajibi, MSc IT Security

Senior Network & Security Engineer · founder of Courseiva

This PCAP practice question is part of Courseiva's free Python Institute certification practice question bank. Courseiva provides original exam-style practice questions with explanations, topic-based practice, mock exams, readiness tracking, and study analytics to help learners prepare for the PCAP exam.