Python online course

Catch Specific Exceptions in Python

Learn how to catch specific Python exceptions with try, except, and else. Handle ValueError, KeyboardInterrupt, multiple exceptions, and invalid user input safely.

What Is an Exception?

An exception is a runtime event that interrupts normal program flow because an operation cannot proceed normally. For example, int() can convert numeric text such as "22", but it cannot convert alphabetic text such as "a".

When an exception is not handled, Python reports the problem with a traceback and usually stops the program. Exception handling lets you respond to expected failures, such as invalid user input, without hiding unrelated programming errors.

Why Catch Exceptions Specifically?

A bare except has no named exception type:

try:
    age = int(input("Enter your age: "))
except:
    print("Something went wrong.")

This catches almost every exception, including errors that your program may not be prepared to handle. A broad handler can make debugging harder because an unrelated bug may appear to have been handled successfully.

Whenever possible, name the anticipated exception type. Each handler should also provide an appropriate response for that particular failure. For invalid numeric input, a useful response is an input-validation message:

try:
    age = int(input("Enter your age: "))
except ValueError:
    print("Invalid value entered.")

The try and except Structure

A try block contains code that may raise an exception. An except clause names an exception type and contains the response that should run when that type is raised in the associated try block.

try:
    # Code that may raise an exception
    result = operation()
except ExceptionType:
    # Response for ExceptionType
    handle_the_problem()

If an exception occurs, normal execution stops inside the try block at the point where the exception is raised. Python then searches for a matching except clause. Statements after the failing line in the try block do not run.

Catching ValueError from User Input

input() returns text. The expression int(input(...)) first asks the user for text and then attempts to convert that text to an integer.

  • Entering 5 or 22 converts successfully.
  • Entering alphabetic text such as a cannot be converted to an integer.
  • Unconvertible text raises the built-in ValueError exception.

Use except ValueError to display a useful message instead of allowing the invalid conversion to produce an unhandled traceback:

try:
    age = int(input("Enter your age: "))
except ValueError:
    print("Please enter a whole number.")

The conversion belongs in the try block because it is the operation expected to fail. The handler responds specifically to a value with an invalid numeric format.

Using else After Successful Exception Handling

An else clause in a try/except structure runs only when the try block completes without raising an exception. Put code that depends on successful conversion in this block.

try:
    age = int(input("Enter your age: "))
except ValueError:
    print("Invalid value entered.")
else:
    if age < 18:
        print("You are under age.")
    else:
        print("You are allowed to continue.")

With input 5, conversion succeeds and the under-age branch runs. With input 22, conversion succeeds and the allowed branch runs. With input a, the ValueError handler runs and the age comparison in else is skipped.

This separates the successful path from the error-handling path. It also ensures that the comparison uses an integer rather than text that failed conversion.

Exception Matching and Unmatched Exceptions

An except ValueError clause catches ValueError only. It does not catch every possible exception.

KeyboardInterrupt is a different built-in exception. It is typically raised when a user interrupts a running program with Ctrl+C. A ValueError handler does not handle that interruption.

If no matching handler exists, the exception continues upward through the program. This is called exception propagation: an unhandled exception keeps moving to an enclosing handler, or eventually ends the program if no handler is found.

Handling Different Exceptions Separately

Use one except clause per exception type when different failures need different responses:

try:
    age = int(input("Enter your age: "))
except ValueError:
    print("Please enter a whole number.")
except KeyboardInterrupt:
    print("You interrupted the program.")
else:
    if age < 18:
        print("You are under age.")
    else:
        print("You are allowed to continue.")

Python selects the handler that matches the exception raised. Non-numeric input selects except ValueError. Pressing Ctrl+C selects except KeyboardInterrupt. A valid integer reaches the else block.

Separate handlers are appropriate when each error requires different behavior, such as different messages, logging, recovery steps, or cleanup.

Handling Several Exception Types in One Handler

When several exception types should receive exactly the same response, list them in an exception tuple:

try:
    age = int(input("Enter your age: "))
except (ValueError, KeyboardInterrupt):
    print("There was an exception.")
else:
    if age < 18:
        print("You are under age.")
    else:
        print("You are allowed to continue.")

The syntax except (ValueError, KeyboardInterrupt): tells Python to use one shared handler for either listed type. Use this form only when the response is intentionally the same.

Separate versus combined exception handlers

Approach: Separate except clauses
Syntax pattern: except ValueError: followed by except KeyboardInterrupt:
When to use it: Each exception needs different behavior.
Message flexibility: Each handler can display its own message.

Approach: One except clause with an exception tuple
Syntax pattern: except (ValueError, KeyboardInterrupt):
When to use it: Several exception types intentionally receive the same response.
Message flexibility: One shared handler and response.

Input and Exception-Handling Outcomes

User action or input: A valid integer below the age threshold
Result of int(input(...)): An integer such as 5
Exception raised: None
Handler or block executed: else
Program response: The under-age branch runs.

User action or input: A valid integer at or above the threshold
Result of int(input(...)): An integer such as 22
Exception raised: None
Handler or block executed: else
Program response: The allowed branch runs.

User action or input: Non-numeric text
Result of int(input(...)): Conversion fails
Exception raised: ValueError
Handler or block executed: except ValueError
Program response: An invalid-input message is displayed.

User action or input: Ctrl+C interruption
Result of int(input(...)): Input is interrupted
Exception raised: KeyboardInterrupt
Handler or block executed: except KeyboardInterrupt, if present
Program response: An interruption message is displayed, or the exception propagates.

Exception-Handling Design Guidance

  • Prefer named exception classes such as ValueError instead of a bare except.
  • Keep the try block focused on the operation expected to fail. A small block makes it easier to identify the source of an exception.
  • Give users friendly messages for expected invalid input.
  • Do not catch exceptions that the program cannot meaningfully recover from.
  • In many application programs, let KeyboardInterrupt propagate so the user can stop the program normally. Catch it only when you deliberately need an interruption message or cleanup behavior.
  • Use separate handlers when different exception types require different responses; use an exception tuple when the response is the same.

Troubleshooting Common Problems

Text input crashes the program

Cause: int() raises ValueError, but no matching handler exists.

Fix: Put the conversion in a try block and add except ValueError.

The age comparison fails

Cause: Comparison logic runs without confirming that integer conversion succeeded.

Fix: Put logic that uses the converted value in the else block.

Ctrl+C is not handled by ValueError

Cause: KeyboardInterrupt and ValueError are different exception types.

Fix: Add except KeyboardInterrupt, or include it in an exception tuple when the response should be the same.

One generic message appears when distinct messages are wanted

Cause: Several exception types were grouped in one tuple handler.

Fix: Use separate except clauses for exception types that need different responses.

Unexpected bugs seem to disappear

Cause: A bare except or overly broad handler is catching errors that were not anticipated.

Fix: Catch only expected exception classes and keep the protected try block narrow.

Key Points

  1. Use try for code that may raise an exception.
  2. Use except ExceptionType to handle a particular exception.
  3. ValueError commonly occurs when int() cannot convert user-entered text.
  4. Use else for code that should run only after the try block succeeds.
  5. Use separate handlers for different responses and an exception tuple for one shared response.
  6. Unmatched exceptions propagate unless another handler catches them.
  7. Avoid bare exception handling because it can hide unrelated errors.

For related control-flow examples, see Python try/except statements, try/except/else statements, and types of errors.