Exception Handling
try-except Statements
Python Exception Handling
Basic Exception Handling
python
# Python - Basic exception handling
def divide_numbers(a, b):
try:
result = a / b
return result
except ZeroDivisionError:
print("Error: Divisor cannot be zero")
return None
except TypeError:
print("Error: Incorrect parameter type")
return None
# Test exception handling
print(divide_numbers(10, 2)) # 5.0
print(divide_numbers(10, 0)) # Error: Divisor cannot be zero
print(divide_numbers("10", 2)) # Error: Incorrect parameter type
# Multiple exception types
def process_data(data):
try:
if isinstance(data, str):
return int(data)
elif isinstance(data, (int, float)):
return data
else:
raise ValueError("Unsupported data type")
except (ValueError, TypeError) as e:
print(f"Data processing error: {e}")
return None
# Test multiple exceptions
print(process_data("123")) # 123
print(process_data(456)) # 456
print(process_data("abc")) # Data processing error: invalid literal for int() with base 10: 'abc'
print(process_data([1, 2, 3])) # Data processing error: Unsupported data typeComplete Exception Handling Structure
python
# Python - Complete exception handling structure
def file_operations(filename):
try:
# Try to open the file
with open(filename, 'r', encoding='utf-8') as f:
content = f.read()
print("File read successfully")
return content
except FileNotFoundError:
print(f"File {filename} not found")
return None
except PermissionError:
print(f"No permission to read file {filename}")
return None
except UnicodeDecodeError:
print(f"File {filename} encoding error")
return None
except Exception as e:
print(f"Unknown error: {e}")
return None
else:
# Executed only if no exception occurs
print("File operation completed")
finally:
# Always executed, whether an exception occurred or not
print("Cleaning up resources")
# Test file operations
file_operations("nonexistent.txt")
file_operations("example.txt")Exception Chaining and Re-throwing
python
# Python - Exception chaining and re-throwing
def low_level_function():
try:
result = 10 / 0
except ZeroDivisionError as e:
raise RuntimeError("Low-level function failed") from e
def high_level_function():
try:
low_level_function()
except RuntimeError as e:
print(f"High-level function caught an error: {e}")
print(f"Original error: {e.__cause__}")
# Test exception chaining
high_level_function()
# Re-throwing an exception
def process_user_input(user_input):
try:
age = int(user_input)
if age < 0 or age > 150:
raise ValueError("Age must be between 0-150")
return age
except ValueError as e:
print(f"Input validation failed: {e}")
raise # Re-throw the exception
# Test re-throwing
try:
age = process_user_input("abc")
except ValueError:
print("Program could not handle invalid input")JavaScript Exception Handling
Basic Exception Handling
javascript
// JavaScript - Basic exception handling
function divideNumbers(a, b) {
try {
const result = a / b;
if (!isFinite(result)) {
throw new Error("Invalid calculation result");
}
return result;
} catch (error) {
if (error.message === "Invalid calculation result") {
console.log("Error: Divisor cannot be zero");
} else {
console.log("Error: Incorrect parameter type");
}
return null;
}
}
// Test exception handling
console.log(divideNumbers(10, 2)); // 5
console.log(divideNumbers(10, 0)); // Error: Divisor cannot be zero
console.log(divideNumbers("10", 2)); // Error: Incorrect parameter type
// Multiple exception types
function processData(data) {
try {
if (typeof data === "string") {
const result = parseInt(data);
if (isNaN(result)) {
throw new Error("Cannot convert to number");
}
return result;
} else if (typeof data === "number") {
return data;
} else {
throw new Error("Unsupported data type");
}
} catch (error) {
console.log(`Data processing error: ${error.message}`);
return null;
}
}
// Test multiple exceptions
console.log(processData("123")); // 123
console.log(processData(456)); // 456
console.log(processData("abc")); // Data processing error: Cannot convert to number
console.log(processData([1, 2, 3])); // Data processing error: Unsupported data typeComplete Exception Handling Structure
javascript
// JavaScript - Complete exception handling structure
async function fileOperations(filename) {
let fileHandle = null;
try {
// Try to open the file
fileHandle = await fs.open(filename, "r");
const content = await fileHandle.readFile("utf-8");
console.log("File read successfully");
return content;
} catch (error) {
if (error.code === "ENOENT") {
console.log(`File ${filename} not found`);
} else if (error.code === "EACCES") {
console.log(`No permission to read file ${filename}`);
} else {
console.log(`Unknown error: ${error.message}`);
}
return null;
} finally {
// Always executed, whether an exception occurred or not
if (fileHandle) {
await fileHandle.close();
}
console.log("Cleaning up resources");
}
}
// Test file operations
fileOperations("nonexistent.txt");
fileOperations("example.txt");Exception Chaining and Re-throwing
javascript
// JavaScript - Exception chaining and re-throwing
function lowLevelFunction() {
try {
const result = 10 / 0;
return result;
} catch (error) {
throw new Error("Low-level function failed", { cause: error });
}
}
function highLevelFunction() {
try {
lowLevelFunction();
} catch (error) {
console.log(`High-level function caught an error: ${error.message}`);
console.log(`Original error: ${error.cause}`);
}
}
// Test exception chaining
highLevelFunction();
// Re-throwing an exception
function processUserInput(userInput) {
try {
const age = parseInt(userInput);
if (isNaN(age) || age < 0 || age > 150) {
throw new Error("Age must be between 0-150");
}
return age;
} catch (error) {
console.log(`Input validation failed: ${error.message}`);
throw error; // Re-throw the exception
}
}
// Test re-throwing
try {
const age = processUserInput("abc");
} catch (error) {
console.log("Program could not handle invalid input");
}Built-in Exceptions
Common Python Exceptions
| Exception | Description |
|---|---|
SyntaxError | Code syntax error |
IndentationError | Indentation error |
NameError | Variable not found |
TypeError | Operation on inappropriate type |
ValueError | Correct type, but inappropriate value |
IndexError | Index out of range for a sequence |
KeyError | Dictionary key not found |
AttributeError | Attribute or method not found |
FileNotFoundError | File not found |
ZeroDivisionError | Division by zero |
Common JavaScript Errors
| Error | Description |
|---|---|
SyntaxError | Code syntax error |
ReferenceError | Invalid reference (e.g., variable not found) |
TypeError | Operation on inappropriate type |
RangeError | Number out of allowed range |
URIError | Error in URI handling functions |
Custom Exceptions
Python Custom Exceptions
python
# Python - Custom exception
class InvalidInputError(ValueError):
"""Custom exception for invalid user input."""
def __init__(self, message="Invalid input provided"):
self.message = message
super().__init__(self.message)
def validate_username(username):
if not isinstance(username, str) or not username.isalnum():
raise InvalidInputError("Username must be alphanumeric")
return True
# Test custom exception
try:
validate_username("user-123")
except InvalidInputError as e:
print(f"Error: {e}")JavaScript Custom Errors
javascript
// JavaScript - Custom error
class InvalidInputError extends Error {
constructor(message = "Invalid input provided") {
super(message);
this.name = "InvalidInputError";
}
}
function validateUsername(username) {
if (typeof username !== "string" || !/^[a-zA-Z0-9]+$/.test(username)) {
throw new InvalidInputError("Username must be alphanumeric");
}
return true;
}
// Test custom error
try {
validateUsername("user-123");
} catch (error) {
if (error instanceof InvalidInputError) {
console.log(`Error: ${error.message}`);
} else {
throw error;
}
}Comparison of Exception Handling
| Feature | Python | JavaScript |
|---|---|---|
| Main Keyword | try...except...else...finally | try...catch...finally |
| Catching Specific Errors | except TypeError: | if (error instanceof TypeError) |
| Getting Error Info | except Exception as e: | catch (error) |
| Custom Exceptions | Inherit from Exception | Inherit from Error |
| Exception Chaining | raise NewError from old_error | new Error("...", { cause: oldError }) |
Summary
- Python: Exception handling is precise, with
exceptblocks for specific exception types. - JavaScript: Uses a general
catchblock, requiring checks on the error object to handle different error types.
Exercises
- Write a function that handles
ZeroDivisionError. - Create a custom exception and throw it.
- Compare how Python and JavaScript handle multiple exception types.
Next Steps
Now you know how to handle exceptions. Next, we'll learn about dependency management.