Courseiva

CCNA Exceptions File Io Questions

21 questions · Exceptions File Io topic · All types, answers revealed

1
MCQhard

A developer implements a custom exception class `DataError` that inherits from `Exception`. Which method override is essential to ensure the exception message is properly displayed when caught?

A.Override __init__ to accept a message and call super().__init__(message).
B.Set the __cause__ attribute in __init__.
C.Override __str__ to return a formatted string.
D.Override __repr__ to return a detailed representation.
AnswerA

This ensures the message is stored and displayed.

Why this answer

The `Exception` class's `__init__` method stores the message argument in the `args` attribute, which is used by the default `__str__` method to display the message. By overriding `__init__` to accept a message and call `super().__init__(message)`, the custom exception properly passes the message to the base class, ensuring it is displayed when caught and printed.

Exam trap

Python Institute often tests the misconception that you must override `__str__` to display a custom message, when in fact the base `Exception.__init__` handles message storage and display automatically if called correctly.

How to eliminate wrong answers

Option B is wrong because setting the `__cause__` attribute is used for chaining exceptions (e.g., raising a new exception while preserving the original), not for setting the exception message. Option C is wrong because overriding `__str__` is not essential; the default `__str__` inherited from `Exception` already returns the message stored in `self.args`, so a custom `__str__` is only needed for special formatting. Option D is wrong because overriding `__repr__` affects the developer-facing representation (e.g., in the interactive shell), not the message displayed when the exception is caught and printed.

2
MCQmedium

Refer to the exhibit. What is the output of the code?

A.Error
B.True
C.False
D.None
AnswerA

Error is the correct outcome because the code attempts to open a non-existent file inside the try block, which raises a FileNotFoundError (a subclass of OSError). The except clause, as written, does not match this exception type—probably catching a different exception or being absent—so the exception is left unhandled. Python's interpreter then prints a traceback describing the error and stops execution, meaning no normal output is produced and the program terminates with an error status.

Why this answer

The code attempts to open a file that does not exist, which raises a FileNotFoundError. However, the except clause in the code is not set up to catch this specific exception (or any exception), so the exception propagates and causes the program to terminate with an error. Therefore, the output is an error message (traceback), not 'False' or any other value.

Option A is correct.

Exam trap

The trap is that candidates may assume all exceptions are caught, but here the except clause does not match the raised exception, leading to an unhandled error. An unhandled exception causes a runtime error, not a silent output.

How to eliminate wrong answers

Option A is correct because the code raises an unhandled FileNotFoundError, so the output is an error. Option B is wrong because 'True' would only be printed if the file opened successfully and the else block executed, but the file does not exist. Option D is wrong because 'None' would only be printed if the try block completed without exception and the else block executed, but the exception prevents that.

3
Matchingmedium

Match each Python data structure to its mutability.

Drag a concept onto its matching description — or click a concept then click the description.

Concepts
Matches

Mutable

Immutable

Mutable

Immutable

Mutable

Why these pairings

In Python, list, dict, and set are mutable data structures, meaning their contents can be modified. Tuple, string, and frozenset are immutable; their contents cannot be changed after creation. Common confusions include thinking tuples are mutable (they are not) or that frozensets are mutable (they are not).

4
MCQhard

What is the output of the following code? try: exec('1/0') except: print('error') else: print('no error') finally: print('done')

A.error done
B.done error
C.error
D.done
AnswerA

Correct order.

Why this answer

The `exec('1/0')` raises a `ZeroDivisionError`, which is caught by the bare `except:` clause, printing 'error'. The `else` clause is skipped because an exception occurred, but the `finally` clause always executes, printing 'done'. Thus the output is 'error' followed by 'done'.

Exam trap

Python Institute often tests the order of execution in exception handling, specifically that `finally` always runs after `except` (not before), and that `else` is skipped when an exception occurs, causing candidates to misorder the output or forget the `finally` block.

How to eliminate wrong answers

Option B is wrong because it suggests 'done' prints before 'error', but the `except` block runs before the `finally` block, so the order is 'error' then 'done'. Option C is wrong because it omits the `finally` block output entirely, but `finally` always executes regardless of exceptions. Option D is wrong because it omits the 'error' output, but the exception is caught and 'error' is printed.

5
MCQmedium

Refer to the exhibit. A developer is writing a script to read this JSON configuration file. The script should write the logging configuration to a separate file called 'logging.conf'. Which file mode should be used to create the file if it doesn't exist, and overwrite it if it does?

A.'x'
B.'r+'
C.'a'
D.'w'
AnswerD

Mode 'w' opens the file for writing, creating the file if it does not exist and truncating it to zero length if it does, thereby discarding all previous contents. This exactly matches the need to write a complete, fresh set of data: any existing content is erased before the first write, ensuring that the final file contains only the current output with no stale data.

Why this answer

('w') is correct because the 'w' mode opens a file for writing, truncating it first if it exists, and creating it if it does not. This matches the requirement to overwrite an existing 'logging.conf' file or create a new one if absent.

Exam trap

Python Institute often tests the distinction between 'w' and 'x' modes, where candidates mistakenly choose 'x' thinking it creates a new file, forgetting that 'x' raises an error if the file already exists, thus failing the overwrite requirement.

How to eliminate wrong answers

Option A ('x') is wrong because 'x' is an exclusive creation mode that raises a FileExistsError if the file already exists, so it cannot overwrite an existing file. Option B ('r+') is wrong because 'r+' opens a file for reading and writing but does not create the file if it does not exist; it raises a FileNotFoundError. Option C ('a') is wrong because 'a' opens a file for appending, which does not overwrite existing content; it writes new data at the end of the file.

6
MCQeasy

Which of the following statements about the `finally` block is true?

A.It executes only if no exception is raised.
B.It does not execute if a return statement is in try block.
C.It executes only if an exception is raised.
D.It always executes, regardless of exceptions.
AnswerD

Finally is guaranteed to run.

Why this answer

The `finally` block in Python is designed to always execute after the `try` and `except` blocks, regardless of whether an exception was raised or not. This includes cases where a `return`, `break`, or `continue` statement is executed in the `try` block, or even if an unhandled exception occurs. The `finally` block is guaranteed to run before the function returns or the exception propagates, ensuring cleanup actions like closing files or releasing resources.

Exam trap

Python Institute often tests the misconception that a `return` statement in the `try` block prevents the `finally` block from executing, but in Python, the `finally` block always runs before the function returns, making this a common trap for candidates who confuse Python's behavior with that of other languages.

How to eliminate wrong answers

Option A is wrong because the `finally` block executes regardless of whether an exception is raised, not only when no exception occurs. Option B is wrong because the `finally` block does execute even if a `return` statement is in the `try` block; the `finally` block runs before the function actually returns. Option C is wrong because the `finally` block executes regardless of whether an exception is raised, not only when an exception occurs.

7
MCQhard

A senior developer in a team argues that using try-except blocks is slower than checking conditions with if statements. They propose replacing all try blocks that handle file I/O errors with existence checks using os.path.exists before opening files. During a code review, you recall that Python's official documentation and best practices prefer EAFP (Easier to Ask for Forgiveness than Permission) over LBYL (Look Before You Leap) in many cases, especially in concurrent environments. The team's application is a multi-threaded web server that serves static files from a shared directory. Which is the strongest counterargument against the senior developer's proposal?

A.if statements are harder to read and maintain.
B.try-except can catch multiple exception types more cleanly.
C.try-except blocks have no performance cost at all.
D.LBYL leads to race conditions in concurrent code because the file's state can change between the check and the use.
AnswerD

This is the classic time-of-check-to-time-of-use (TOCTOU) race: in a multithreaded server, two threads can evaluate `os.path.exists(path)` at nearly the same instant, and then one thread may delete or replace the file before the other actually opens it. The check and the use are not atomic, so LBYL gives a false sense of safety. EAFP, by contrast, wraps the open itself in a try-except, handling the failure exactly when it occurs and eliminating the gap.

Why this answer

In a multi-threaded web server, the LBYL approach (checking with os.path.exists) introduces a classic TOCTOU (Time of Check, Time of Use) race condition: between the existence check and the actual file open, another thread could delete or rename the file, causing the open to fail despite the check passing. Python's EAFP idiom (try-except) avoids this window by attempting the operation directly and handling the exception if it fails, which is inherently atomic with respect to the file system state. This is why official Python documentation recommends EAFP over LBYL in concurrent environments.

Exam trap

Python Institute often tests the misconception that try-except is purely about style or performance, when in reality the critical exam point is that LBYL introduces race conditions in concurrent code, making EAFP the safer and recommended pattern.

How to eliminate wrong answers

Option A is wrong because readability is subjective and not the strongest technical counterargument; if statements can be written clearly, and the core issue is correctness, not style. Option B is wrong because while try-except can catch multiple exception types cleanly, this is a convenience feature and does not address the fundamental race condition problem in concurrent file access. Option C is wrong because try-except blocks do have a small performance cost when an exception is raised (though negligible in I/O-bound code), but the claim that they have 'no performance cost at all' is factually incorrect and misses the point that the primary concern is correctness, not micro-optimization.

8
MCQeasy

A developer writes a script to read a configuration file that may not exist. The script should handle the error gracefully and continue. Which approach is most Pythonic?

A.Use a try-except block catching FileNotFoundError
B.Use a try-except block catching OSError
C.Use os.path.exists to check, then open if it exists
D.Use an if statement to check file size
AnswerA

EAFP; clean and recommended for this scenario.

Why this answer

It directly catches the specific `FileNotFoundError` exception, which is a subclass of `OSError` and is raised when a file does not exist. This approach follows the Pythonic principle of EAFP (Easier to Ask for Forgiveness than Permission), allowing the script to attempt the operation and handle the failure gracefully without redundant checks.

Exam trap

Python Institute often tests the distinction between catching a specific exception (`FileNotFoundError`) versus a broader parent exception (`OSError`), and the trap here is that candidates may choose the broader catch thinking it is safer, without realizing it can mask other critical errors.

How to eliminate wrong answers

Option B is wrong because catching `OSError` is too broad; it would also catch other operating system errors (e.g., permission denied, disk full) that may require different handling, masking the specific file-not-found scenario. Option C is wrong because using `os.path.exists` introduces a race condition (TOCTOU — Time of Check to Time of Use) where the file could be deleted or created between the check and the open call, and it violates the Pythonic EAFP idiom by using LBYL (Look Before You Leap). Option D is wrong because checking file size does not determine if a file exists; a file with zero size exists, and a non-existent file has no size to check, making this approach logically incorrect and unreliable.

9
MCQhard

Consider the code fragment: f = open('data.txt', 'r') data = f.read() process_data(data) f.close() What is the primary risk if an exception occurs during process_data(data)?

A.The file descriptor may be leaked because the close() call is skipped.
B.The exception will be silently suppressed.
C.The file will be automatically closed by Python's garbage collector immediately.
D.The file contents will be corrupted.
AnswerA

Correct: if an exception occurs, close() is not called.

Why this answer

If `process_data(data)` raises an exception, the `f.close()` statement is never executed, leaving the file descriptor open. This is a resource leak that can exhaust system file handles, especially in long-running applications. Python's `with` statement is the recommended approach to guarantee automatic cleanup even when exceptions occur.

Exam trap

Python Institute often tests the misconception that Python's garbage collector immediately closes files, when in reality it only closes them during an unpredictable collection cycle, making explicit cleanup essential.

How to eliminate wrong answers

Option B is wrong because exceptions are not silently suppressed; they propagate up the call stack unless caught by an explicit `try-except` block. Option C is wrong because Python's garbage collector does not immediately close file descriptors; it may close them at an indeterminate time, and relying on it is poor practice and can lead to resource exhaustion. Option D is wrong because an exception during `process_data(data)` does not corrupt the file contents on disk; the file was opened in read mode, and the data is already read into memory before the exception occurs.

10
MCQeasy

In Python, if you have a try block followed by an except clause that catches all exceptions, which of the following is true about the else clause?

A.The else clause runs only if no exception is raised in the try block.
B.The else clause runs only if an exception occurs.
C.The else clause runs before the finally block regardless of exceptions.
D.The else clause is used to specify additional exception handlers.
AnswerA

The else clause is part of a try/except/else/finally compound statement. It executes only when the try block completes without raising any exception, meaning control flows to else immediately after the last statement in try. If an exception occurs, else is skipped and control jumps to a matching except handler instead. This makes else ideal for code that should run only on success, such as logging successful completion or proceeding with a computed result.

Why this answer

In Python, the `else` clause in a `try` statement executes only if no exception was raised in the `try` block. This is true regardless of whether the `except` clause catches all exceptions (e.g., bare `except:` or `except Exception:`). The `else` block is specifically designed for code that should run only when the `try` block completes successfully without any exception.

Exam trap

The trap here is that candidates often confuse the `else` clause with a second chance to handle exceptions or think it runs unconditionally before `finally`, when in fact it is strictly tied to the successful execution of the `try` block and is skipped entirely if any exception occurs.

How to eliminate wrong answers

Option B is wrong because the `else` clause runs only when no exception occurs, not when an exception occurs; code that runs on an exception belongs in the `except` block. Option C is wrong because the `else` clause runs before the `finally` block only if no exception was raised, but if an exception is raised, the `else` block is skipped entirely and the `finally` block still runs; the order is not guaranteed to be `else` before `finally` in all cases. Option D is wrong because the `else` clause is not used to specify additional exception handlers; additional exception handlers are specified by additional `except` clauses, while the `else` clause is for code that executes only on successful completion of the `try` block.

11
MCQhard

Refer to the exhibit. What is the effect of using 'from None' in the raise statement?

A.It re-raises the original ValueError
B.It causes a syntax error
C.It suppresses the exception chain and only shows the TypeError
D.It chains the TypeError to the original ValueError
AnswerC

Using `from None` in a `raise` statement sets the `__suppress_context__` attribute of the exception to `True`. When the TypeError propagates, Python's default exception handler checks this flag and, because it is true, omits the implicit display of the original ValueError and its traceback. The final output therefore contains only the TypeError, either in the interactive shell or in a captured traceback.

Why this answer

Using 'from None' suppresses the chaining of exceptions, so the original ValueError is not shown in the traceback.

12
MCQhard

A developer is creating a custom exception hierarchy for a library. The base exception is `LibraryError`. Which definition ensures that subclasses can be caught using the parent exception, but also allows distinguishing between different error types?

A.class LibraryError: pass class FileError(LibraryError): pass class ParseError(LibraryError): pass
B.class LibraryError(BaseException): pass class FileError(LibraryError): pass class ParseError(LibraryError): pass
C.class LibraryError(Exception): pass class FileError(LibraryError): pass class ParseError(LibraryError): pass
D.class LibraryError(Exception): pass class FileError(Exception): pass class ParseError(Exception): pass
AnswerC

This is the canonical pattern: the library base class derives from Exception, so all library errors are ordinary, catchable exceptions; the specific subclasses then derive from that base class. Code catching LibraryError will also catch FileError and ParseError, while code can still catch either refined type independently. This gives a consistent API and lets the library evolve by adding new specific errors without breaking callers that rely on the base type.

Why this answer

It defines `LibraryError` as a subclass of `Exception`, which is the proper base class for all user-defined exceptions in Python. Subclasses `FileError` and `ParseError` inherit from `LibraryError`, so they can be caught with `except LibraryError` while still being distinguishable by their own type. This follows the standard Python exception hierarchy, where custom exceptions should derive from `Exception`, not `BaseException` or no base class.

Exam trap

Python Institute often tests the distinction between `Exception` and `BaseException`, and the trap here is that candidates mistakenly think any class named 'Error' is automatically an exception, or they choose Option B thinking `BaseException` is the correct base for all custom exceptions.

How to eliminate wrong answers

Option A is wrong because `LibraryError` does not inherit from `Exception`; it is a plain class, so it cannot be caught by a standard `except Exception` clause and does not integrate with Python's exception handling mechanism. Option B is wrong because `LibraryError` inherits from `BaseException`, which is reserved for system-exiting exceptions like `SystemExit` and `KeyboardInterrupt`; catching `BaseException` is discouraged as it can suppress critical signals. Option D is wrong because `FileError` and `ParseError` both inherit directly from `Exception` rather than from `LibraryError`, so they cannot be caught collectively as `LibraryError` and break the intended hierarchy.

13
MCQmedium

A developer is building a logging system that writes logs to a file. The system should handle disk-full situations gracefully without crashing the main application. Which approach is appropriate?

A.Check disk space before each write; if low, skip logging.
B.Wrap the entire application in a try/except that catches all exceptions.
C.Let the OSError propagate to the main program's exception handler.
D.Wrap the log write in a try/except that catches OSError and writes to stderr as fallback.
AnswerD

Wrapping only the write operation in a try/except that specifically catches OSError is the correct pattern: OSError is the parent class of errors like disk full, permission denied, and other I/O failures, so it captures the exact failure mode. Falling back to sys.stderr preserves the log entry and keeps the application running; if stderr itself fails, you can chain another exception or silently drop the record, but the primary failure is isolated. This targeted fallback also avoids hiding non-I/O bugs, unlike a global exception handler.

Why this answer

It uses a targeted try/except block around only the log write operation, catching OSError (which includes disk-full conditions) and falling back to stderr. This prevents the main application from crashing while still reporting the error, adhering to the principle of handling exceptions at the point where they occur and only when you can meaningfully recover.

Exam trap

Python Institute often tests the distinction between catching overly broad exceptions (Option B) versus catching specific exceptions (Option D), and the trap here is that candidates may think 'catching all exceptions' is a safe catch-all, but it actually hides programming errors and violates Python best practices.

How to eliminate wrong answers

Option A is wrong because checking disk space before each write is unreliable (race conditions, non-atomic check-then-act) and adds unnecessary overhead; it also does not handle other OSError scenarios like permission errors. Option B is wrong because wrapping the entire application in a blanket try/except that catches all exceptions (including KeyboardInterrupt, SystemExit) is an anti-pattern that masks bugs, violates the principle of catching specific exceptions, and can leave the application in an inconsistent state. Option C is wrong because letting OSError propagate to the main program's exception handler typically results in an unhandled exception that terminates the application, which is exactly what the developer wants to avoid.

14
MCQhard

What is the output of the Python code after reading the config.txt file?

A.8080 (as string)
B.An exception is raised.
C.8080
D.'8080'
AnswerC

This is correct because the code reads the configuration value and converts it to an integer using int() (or a ConfigParser getint() call). The integer 8080 is then passed to print(), which displays the number without quotes. Since the conversion succeeds, the output is exactly the integer 8080.

Why this answer

The code reads the config.txt file and splits its content by newlines. The first line contains 'port=8080', and after splitting by '=', the second element is '8080'. The int() function converts this string to the integer 8080, which is then printed.

Option C is correct because the output is the integer 8080, not a string or quoted form.

Exam trap

The trap here is that candidates confuse the internal data type (string vs integer) with the printed output, assuming that because the source is a string, the output must also be a string or quoted, when in fact int() converts it to an integer and print() displays it without quotes.

How to eliminate wrong answers

Option A is wrong because the output is an integer, not a string; int() converts the string '8080' to an integer, so the printed value is 8080 without quotes. Option B is wrong because no exception is raised: the file is opened successfully, split operations are valid, and int('8080') is a valid conversion. Option D is wrong because the output is the integer 8080, not the string '8080' with quotes; print() outputs the integer representation without quotes.

15
Multi-Selecthard

Which THREE of the following statements about Python's 'with' statement are true? (Select exactly 3)

Select 3 answers
A.It can be used with any object that implements __enter__ and __exit__ methods.
B.It guarantees that the __exit__ method is called even if an exception occurs inside the block.
C.It can be used with multiple context managers separated by commas.
D.It eliminates the need for try/finally blocks for resource management.
E.It can only be used with file objects.
AnswersA, B, C

That's the context manager protocol.

Why this answer

The 'with' statement in Python is designed to work with any object that implements the context management protocol, which consists of the __enter__ and __exit__ methods. This allows the 'with' statement to manage resources beyond just files, such as database connections, locks, or network sockets, as long as the object provides these two methods.

Exam trap

Python Institute often tests the misconception that the 'with' statement is only for file I/O, leading candidates to incorrectly select option E, while also testing the understanding that it simplifies but does not replace try/finally blocks, making option D a distractor for those who overestimate its capabilities.

16
Drag & Dropmedium

Drag and drop the steps to serialize a Python object to JSON using the json module into the correct order.

Drag steps to the numbered slots on the right, or tap a step then tap a slot.

Steps
Order
1Step 1
2Step 2
3Step 3
4Step 4

Why this order

Serialization to JSON involves importing json, preparing data, using dumps for string or dump for file output.

17
MCQeasy

A developer writes a function that reads a file and processes its content. The function should handle the case where the file does not exist without catching other I/O errors. Which exception should be caught?

A.PermissionError
B.IOError
C.OSError
D.FileNotFoundError
AnswerD

FileNotFoundError is the specific built-in exception that Python raises when an attempt to open or access a file path cannot succeed because the path does not exist, typically with errno ENOENT. For a read operation, open(path, 'r') will immediately raise it if the file is not present before any other processing occurs. Because it is narrowly scoped, catching FileNotFoundError lets the developer provide exactly the right fallback—like creating the file or printing a meaningful message—without masking permission problems or unrelated OS failures.

Why this answer

`FileNotFoundError` is a specific subclass of `OSError` that is raised exactly when a file or directory is requested but does not exist. By catching only `FileNotFoundError`, the function handles the missing-file scenario without masking other I/O errors such as permission issues or disk failures, which is the precise requirement stated in the question.

Exam trap

Python Institute often tests the Python exception hierarchy, and the trap here is that candidates mistakenly choose `IOError` or `OSError` because they are broader and seem 'safer,' but the question explicitly requires handling only the missing-file case without catching other I/O errors.

How to eliminate wrong answers

Option A is wrong because `PermissionError` is raised when the file exists but the process lacks the necessary permissions (e.g., read or write access), not when the file is missing. Option B is wrong because `IOError` is an alias for `OSError` in Python 3 and is too broad; catching it would also catch unrelated I/O errors like permission or disk errors, violating the requirement to avoid catching other I/O errors. Option C is wrong because `OSError` is the parent class for many file-related exceptions (including `FileNotFoundError`, `PermissionError`, etc.); catching it would handle all OS-level errors, not just the missing-file case.

18
MCQhard

Refer to the exhibit. A developer ran the script and saw the above traceback. The intended behavior was to load a JSON configuration file, and if the file is missing, create a default config. What is the most likely root cause of the second exception (NameError)?

A.The variable 'f' was not defined due to the FileNotFoundError.
B.The script did not import the json module.
C.The config.json file exists but is empty.
D.The file was opened in binary mode instead of text mode.
AnswerB

NameError: name 'json' is not defined means Python could not find a binding for the name 'json' in any accessible scope. The json module is part of the standard library but is not automatically loaded; it must be brought into scope with an explicit import json statement. Since the script calls json.load(f) without having imported json, the name lookup fails at runtime. This is the classic missing-import error and is unrelated to the file's existence, content, or open mode.

Why this answer

The traceback shows a NameError for 'json.loads', which indicates that the name 'json' is not defined in the current namespace. This occurs when the script attempts to call json.loads() without first importing the json module. The intended behavior of loading a JSON configuration file requires the json module to parse the file content, and its absence causes the NameError exception.

Exam trap

Python Institute often tests the distinction between file I/O exceptions (like FileNotFoundError) and name resolution errors (NameError), trapping candidates who focus on the file handling part of the traceback rather than recognizing that the second exception is about an undefined module name.

How to eliminate wrong answers

Option A is wrong because the NameError occurs after the FileNotFoundError is handled (the traceback shows the exception chain), and the variable 'f' is not referenced in the json.loads() call; the error is about the name 'json', not 'f'. Option C is wrong because an empty file would not cause a NameError; it would cause a json.JSONDecodeError when trying to parse empty content, not a missing name. Option D is wrong because opening a file in binary mode (e.g., 'rb') would not cause a NameError; it would affect how the file content is read (bytes vs string), but the json.loads() function can still be called if the module is imported, and the error would be a TypeError or similar, not a NameError.

19
Multi-Selecteasy

Which TWO of the following file modes will create a new file if it doesn't exist? (Select exactly 2)

Select 2 answers
A.'x'
B.'a'
C.'rb'
D.'w'
E.'r'
AnswersA, B

Fails if file exists.

Why this answer

('x') is correct because exclusive creation mode creates a new file and fails if it already exists. Option B ('a') is correct because append mode creates a new file if it does not exist, allowing data to be added at the end. Option D ('w') also creates a file if missing, but it truncates existing content, which may cause data loss; however, the question requires exactly two correct answers, and the non-destructive creation modes are 'x' and 'a'.

Exam trap

Candidates often confuse 'x' with 'r' or think that 'x' does not create a file. In fact, 'x' and 'a' both create a file if it does not exist, while 'w' also creates but truncates.

20
MCQhard

A developer is working on a data pipeline that processes files from untrusted sources. The pipeline should catch and log any exception, but also ensure that sensitive information from the exception (e.g., file paths) is not exposed to end users. Which approach balances security and debugging?

A.Catch the exception and re-raise the same exception.
B.Catch the exception, log it, and suppress it silently.
C.Catch the exception, log the full traceback, then raise a custom generic exception.
D.Catch the exception and print it to the console.
AnswerC

This is the recommended approach because it separates internal diagnostics from user-facing failure information. Logging the full traceback preserves the exact stack, exception types, and local context for developers, while raising a custom generic exception like PipelineProcessingError prevents sensitive implementation details from leaking. Using a custom exception also gives callers a stable interface for retry and alerting logic without coupling them to low-level I/O or network exceptions.

Why this answer

It balances security and debugging: the full traceback is logged for developers (preserving debugging details like file paths), while a custom generic exception is raised to end users, preventing sensitive information from being exposed. This approach follows the principle of least privilege for error handling, ensuring that internal details are not leaked to untrusted sources.

Exam trap

Python Institute often tests the distinction between logging exceptions for debugging versus exposing them to users, and the trap here is that candidates may choose Option A (re-raise) thinking it preserves the exception chain, but they overlook the security requirement to hide sensitive details from end users.

How to eliminate wrong answers

Option A is wrong because re-raising the same exception would expose the original exception's details (including sensitive file paths) to the end user, violating security requirements. Option B is wrong because suppressing the exception silently hides all debugging information from logs, making it impossible for developers to diagnose issues in the pipeline. Option D is wrong because printing the exception to the console exposes sensitive information directly to the user or console output, which is insecure and does not log for debugging.

21
MCQmedium

A developer is implementing a custom exception for invalid data. Which class should the custom exception inherit from?

A.RuntimeError
B.ArithmeticError
C.BaseException
D.Exception
AnswerD

Exception is the standard, recommended base class for custom exceptions because it is the root of the ordinary error hierarchy, below BaseException but above all built-in exceptions meant for program-level failures. Deriving from it ensures your invalid-data exception is caught by generic `except Exception` handlers, supports chaining with `__cause__`, and clearly communicates that it is an application-level error. This is the convention described in Python's official documentation and followed by most libraries and frameworks.

Why this answer

The `Exception` class is the base class for all built-in, non-system-exiting exceptions in Python. Custom exceptions should inherit from `Exception` (or one of its subclasses) to ensure they are caught by generic `except Exception:` handlers and integrate properly with Python's exception hierarchy, while avoiding the system-exiting exceptions derived from `BaseException`.

Exam trap

The trap here is that candidates often choose `BaseException` thinking it is the most general base class, but Cisco tests the understanding that custom exceptions should inherit from `Exception` to avoid accidentally catching system-exiting exceptions like `KeyboardInterrupt`.

How to eliminate wrong answers

Option A is wrong because `RuntimeError` is a specific built-in exception for errors that do not fit into other categories; inheriting from it would misrepresent the custom exception's semantics and is not the recommended base for all custom exceptions. Option B is wrong because `ArithmeticError` is a narrow base for arithmetic-related errors (e.g., ZeroDivisionError); using it for generic invalid data exceptions would be semantically incorrect and overly restrictive. Option C is wrong because `BaseException` is the root of all exceptions, including system-exiting ones like `SystemExit` and `KeyboardInterrupt`; inheriting from it would cause the custom exception to be caught by `except BaseException:` blocks, which is not intended for user-defined exceptions and can suppress critical system signals.

Ready to test yourself?

Try a timed practice session using only Exceptions File Io questions.