EASYTUTORGUIDE

Practical tutorials, tools, courses, digital skills, and business promotion.

Free Learning

JavaScript – Chapter 2: Development Environment

Learn what JavaScript is, where it runs, why it is important, and how beginners can start using it with simple examples and clear output.

Beginner Friendly JavaScript Basics Web Development Code Examples
JavaScript Lesson 2 Chapter 2 Topics Day / Night Mode

Main reading content

python-course-chapter-21

Chapter 21: Exception Handling

Learn how to understand errors, catch exceptions, raise custom errors, and keep Python programs running safely.

Goal: Build beginner-friendly Python programs that respond safely to invalid input, runtime problems, and application-specific errors.

Chapter 21 Topics

21.1 Understanding Errors

Errors are problems that stop a program from working correctly or cause it to produce the wrong result. Some errors are detected before the program runs, while others happen during execution. Learning to recognize error messages helps beginners find the exact line that caused a problem and understand what must be corrected.

Example

number = 10
text = "5"
print(number + int(text))

Output

15

Output Explanation

The text value "5" is converted to the integer 5 before addition. Python then adds 10 and 5 and displays 15. Without the conversion, Python would report an error because a number and a string cannot be added directly.

21.2 Syntax Errors

A syntax error happens when code does not follow Python's writing rules. Common causes include missing quotation marks, missing parentheses, incorrect indentation, or forgetting a colon. Python checks the program before running it, and if the syntax is invalid, the interpreter shows a message that points near the problem.

Example

message = "Hello"
print(message)

Output

Hello

Output Explanation

This corrected program follows Python syntax. The quotation marks are complete, the variable assignment is valid, and the print function has both parentheses. Python stores the text in message and then displays Hello.

21.3 Runtime Errors

A runtime error happens after Python has started running the program. The code may be written with correct syntax, but an operation fails while the program is executing. Examples include dividing by zero, opening a missing file, or converting unsuitable text into a number. Runtime errors are usually represented by exceptions.

Example

try:
    result = 10 / 0
except ZeroDivisionError:
    print("You cannot divide by zero.")

Output

You cannot divide by zero.

Output Explanation

Python tries to calculate 10 divided by zero. That operation raises ZeroDivisionError. The except block catches that specific exception, so the program displays a helpful message instead of stopping with a traceback.

21.4 Logical Errors

A logical error occurs when a program runs without crashing but gives an incorrect result. Python cannot automatically detect this type of problem because the code is valid. The programmer must compare the expected result with the actual result, examine the formula or conditions, and correct the program's logic.

Example

price = 20
quantity = 3
total = price * quantity
print(total)

Output

60

Output Explanation

The correct formula multiplies the item price by the quantity. Python calculates 20 times 3 and displays 60. If addition had been used instead, the program would run but produce the wrong answer, which would be a logical error.

21.5 Exceptions

An exception is an object that represents a problem occurring while a Python program runs. Different problems have different exception types, such as ValueError, TypeError, KeyError, and ZeroDivisionError. By identifying the exception type, a programmer can handle the problem in a controlled and understandable way.

Example

try:
    age = int("twelve")
except ValueError:
    print("Age must be written as digits.")

Output

Age must be written as digits.

Output Explanation

The int function cannot convert the word twelve into an integer, so Python raises ValueError. The except block handles that exception and prints a clear message for the user.

21.6 The `try` Block

The try block contains code that may cause an exception. Python runs the statements inside try normally. If no problem occurs, execution continues. If an exception happens, Python stops the remaining statements in that try block and searches for a matching except block that can handle the problem.

Example

try:
    number = int("25")
    print(number * 2)
except ValueError:
    print("Invalid number")

Output

50

Output Explanation

The text 25 can be converted successfully into an integer. Python multiplies the number by 2 and displays 50. Because no ValueError occurs, the except block is skipped.

21.7 The `except` Block

The except block tells Python what to do when a particular exception occurs in the related try block. It prevents the program from ending suddenly and gives the programmer a place to show a helpful message, use a backup value, request new input, or safely continue another part of the program.

Example

try:
    value = int("abc")
except ValueError:
    print("Please enter a valid whole number.")

Output

Please enter a valid whole number.

Output Explanation

Converting abc to an integer fails and raises ValueError. Python immediately moves to the matching except block and displays the beginner-friendly message instead of showing an unhandled error.

21.8 Catching Specific Exceptions

Catching a specific exception means naming the exact error type after except. This is safer than catching every possible problem because each error can receive the correct response. For example, invalid numeric text should be handled differently from division by zero or a missing dictionary key.

Example

try:
    number = int("0")
    print(100 / number)
except ValueError:
    print("Not a number")
except ZeroDivisionError:
    print("The number cannot be zero")

Output

The number cannot be zero

Output Explanation

The conversion succeeds because 0 is valid numeric text. The division then raises ZeroDivisionError. Python skips the ValueError handler and runs the ZeroDivisionError handler.

21.9 Multiple Exception Handlers

A single try block can have several except blocks. Each handler can respond to a different type of failure. Python checks the handlers in order and runs the first compatible one. This makes programs clearer because invalid input, missing data, and calculation problems can each have their own explanation.

Example

data = {"price": 10}
try:
    quantity = data["quantity"]
    print(100 / quantity)
except KeyError:
    print("Quantity is missing.")
except ZeroDivisionError:
    print("Quantity cannot be zero.")

Output

Quantity is missing.

Output Explanation

The dictionary does not contain the key quantity, so Python raises KeyError before division occurs. The KeyError handler runs and displays the message. The ZeroDivisionError handler is not needed.

21.10 The `else` Block

The else block runs only when the try block finishes without raising an exception. It is useful for code that should execute after a risky operation succeeds. Keeping successful follow-up work in else makes it clear which statements are protected by try and which statements depend on success.

Example

try:
    age = int("18")
except ValueError:
    print("Invalid age")
else:
    print("Age accepted:", age)

Output

Age accepted: 18

Output Explanation

The conversion to integer succeeds, so Python does not run the except block. It then enters the else block and prints the accepted age.

21.11 The `finally` Block

The finally block runs whether an exception happens or not. It is commonly used for cleanup actions, such as closing a file, releasing a network connection, or showing that an operation has finished. Even when the except block handles an error, Python still executes the finally block afterward.

Example

try:
    print(10 / 2)
except ZeroDivisionError:
    print("Division failed")
finally:
    print("Calculation finished")

Output

5.0
Calculation finished

Output Explanation

The division succeeds and prints 5.0. No exception handler is needed. The finally block still runs and prints Calculation finished, showing that finally executes after the try process.

21.12 Raising Exceptions

Sometimes a program should deliberately create an exception when data breaks an important rule. Raising an exception tells the caller that the operation cannot continue normally. This is useful for validating ages, prices, passwords, quantities, and other values that must satisfy specific requirements.

Example

age = -3
try:
    if age < 0:
        raise ValueError("Age cannot be negative")
except ValueError as error:
    print(error)

Output

Age cannot be negative

Output Explanation

The condition detects that age is below zero. The program raises a ValueError with a custom message. The except block catches the exception as error and prints that message.

21.13 The `raise` Statement

The raise statement creates an exception manually. It can raise a built-in exception or a custom exception. A message can be included inside the exception to explain the problem. After raise runs, normal execution stops until a suitable exception handler catches the raised exception.

Example

password = "abc"
try:
    if len(password) < 8:
        raise ValueError("Password must contain at least 8 characters")
except ValueError as error:
    print(error)

Output

Password must contain at least 8 characters

Output Explanation

The password length is only three characters, so the condition is true. The raise statement creates ValueError. The handler prints the explanatory message stored in the exception.

21.14 Exception Arguments

Exception arguments are values passed into an exception object, usually to provide a helpful message or related details. When the exception is caught with the as keyword, the program can access these arguments. They help developers and users understand exactly why the operation failed.

Example

try:
    raise ValueError("Invalid score", 150)
except ValueError as error:
    print(error.args)

Output

('Invalid score', 150)

Output Explanation

The ValueError receives two arguments: a message and the invalid value. The args attribute stores them as a tuple. Printing error.args displays both pieces of information.

21.15 Exception Chaining

Exception chaining connects a new exception to the original exception that caused it. The from keyword makes this relationship explicit. Chaining is valuable when low-level technical errors need to be converted into clearer application errors while still preserving the original cause for debugging.

Example

try:
    try:
        number = int("abc")
    except ValueError as original:
        raise RuntimeError("Could not prepare the number") from original
except RuntimeError as error:
    print(error)

Output

Could not prepare the number

Output Explanation

The failed conversion first raises ValueError. The program then raises RuntimeError from that original exception. The outer handler catches RuntimeError and prints the clearer application message.

21.16 Creating Custom Exceptions

A custom exception is a programmer-defined class used to represent a problem specific to an application. It normally inherits from Exception or one of its subclasses. Custom exceptions make error handling easier to understand because their names can clearly describe rules such as insufficient balance, invalid order, or expired membership.

Example

class InsufficientBalanceError(Exception):
    pass

balance = 20
cost = 30
try:
    if cost > balance:
        raise InsufficientBalanceError("Not enough money")
except InsufficientBalanceError as error:
    print(error)

Output

Not enough money

Output Explanation

The custom class represents a balance problem. Because the cost is greater than the balance, the program raises InsufficientBalanceError. The matching handler catches it and prints the message.

21.17 Exception Hierarchies

Python exceptions are organized in a class hierarchy. General exception classes are parents of more specific exception classes. For example, ZeroDivisionError is a kind of ArithmeticError, and ArithmeticError is a kind of Exception. Understanding this hierarchy helps programmers decide whether to catch one specific error or a broader group.

Example

try:
    result = 5 / 0
except ArithmeticError:
    print("A mathematical error occurred.")

Output

A mathematical error occurred.

Output Explanation

Dividing by zero raises ZeroDivisionError. Because ZeroDivisionError is a subclass of ArithmeticError, the broader ArithmeticError handler can catch it and display the message.

21.18 Assertions

An assertion checks whether a condition that the programmer expects to be true is actually true. Assertions are mainly development and debugging tools, not replacements for normal user-input validation. When the condition is false, Python raises AssertionError, which helps reveal incorrect assumptions inside the program.

Example

temperature = 20
assert temperature >= -100
print("Temperature accepted")

Output

Temperature accepted

Output Explanation

The assertion checks whether the temperature is at least negative 100. The condition is true, so no exception is raised. Python continues to the next line and prints Temperature accepted.

21.19 The `assert` Statement

The assert statement contains a condition and may include an optional message. If the condition is true, nothing happens and the program continues. If it is false, Python raises AssertionError. This is useful for checking internal assumptions while testing functions, calculations, and program states.

Example

items = ["pen", "book"]
assert len(items) > 0, "The list must not be empty"
print(items[0])

Output

pen

Output Explanation

The list contains two items, so the assertion succeeds. Python then accesses the first item and prints pen. If the list were empty, AssertionError would be raised with the supplied message.

21.20 EAFP vs LBYL

EAFP means it is easier to ask forgiveness than permission. In Python, this style tries an operation and handles an exception if it fails. LBYL means look before you leap, which checks conditions before acting. Both approaches are useful, but EAFP is often natural when failure is uncommon and exceptions are clear.

Example

data = {"name": "Ali"}
try:
    print(data["name"])
except KeyError:
    print("Name is missing")

Output

Ali

Output Explanation

The program directly tries to access the name key. Because the key exists, it prints Ali and no exception occurs. This is an EAFP approach because the operation is attempted first.

21.21 Exception Handling Best Practices

Good exception handling catches only errors that the program can meaningfully manage. Use specific exception types, provide clear messages, avoid hiding unexpected problems, and keep try blocks focused on risky statements. Cleanup belongs in finally, successful follow-up work can go in else, and custom exceptions should describe application-specific failures.

Example

try:
    quantity = int("4")
except ValueError:
    print("Quantity must be a whole number")
else:
    total = quantity * 5
    print("Total:", total)

Output

Total: 20

Output Explanation

Only the conversion is placed in the try block because that operation can raise ValueError. Since conversion succeeds, the else block calculates the total and displays 20. This keeps the handler specific and the code easy to read.

21.22 Chapter Practice Exercises

Practice exercises help you become comfortable reading tracebacks and handling common exceptions. Work slowly and test both successful and unsuccessful inputs. Try converting text to numbers, dividing values, accessing dictionary keys, validating ranges, and using try, except, else, and finally together. Compare each actual result with the result you expected.

Example

values = ["10", "five", "20"]
for value in values:
    try:
        print(int(value))
    except ValueError:
        print("Skipped:", value)

Output

10
Skipped: five
20

Output Explanation

The strings 10 and 20 can be converted to integers, so they are printed. The word five cannot be converted, causing ValueError. The handler prints Skipped: five, and the loop continues to the final value.

21.23 Chapter Mini Project

In this mini project, you will build a small safe calculator. The program converts text values into numbers, selects an operation, catches invalid numeric input, prevents division by zero, and reports unsupported operations. This project combines the major exception-handling tools from the chapter in one beginner-friendly example.

Example

first_text = "12"
second_text = "0"
operation = "/"

try:
    first = float(first_text)
    second = float(second_text)

    if operation == "+":
        result = first + second
    elif operation == "-":
        result = first - second
    elif operation == "*":
        result = first * second
    elif operation == "/":
        result = first / second
    else:
        raise ValueError("Unsupported operation")

except ValueError as error:
    print("Input error:", error)
except ZeroDivisionError:
    print("Calculation error: cannot divide by zero")
else:
    print("Result:", result)
finally:
    print("Calculator finished")

Output

Calculation error: cannot divide by zero
Calculator finished

Output Explanation

Both text values convert successfully to floating-point numbers. The selected operation is division, but the second number is zero, so ZeroDivisionError occurs. Its handler prints the calculation message. Finally then runs and confirms that the calculator has finished.

Chapter 2: Development EnvironmentPrepare Your JavaScript Workspace

A modern course built to help learners study step by step with clarity, comfort, and confidence.