try: # Read a number from a file with open('number.txt', 'r') as f: text = f.read() number = int(text) result = 100 / number print(f"Result: {result}")except FileNotFoundError: print("Could not find number.txt")except ValueError: print("File doesn't contain a valid number")except ZeroDivisionError: print("Cannot divide by zero")
try: with open('data.txt', 'r') as f: data = f.read()except FileNotFoundError: print("File not found")else: # This only runs if the file was opened successfully print(f"File has {len(data)} characters")
try: file = open('data.txt', 'r') data = file.read()except FileNotFoundError: print("File not found")finally: # This always runs to clean up if 'file' in locals() and not file.closed: file.close() print("Cleanup complete")
Don’t catch all errors with a bare except:. It hides problems and makes debugging harder. Always catch specific error types when possible.
# Bad - catches everythingtry: process_data()except: pass # Silent failure!# Good - specific errortry: process_data()except ValueError: print("Invalid data format")
Empty except blocks
Copy
# Bad - ignores the errortry: risky_operation()except ValueError: pass# Good - at least log ittry: risky_operation()except ValueError: print("Warning: Invalid value encountered")
Not re-raising critical errors
Copy
# Bad - hides all errorstry: critical_operation()except Exception as e: print(f"Error: {e}")# Good - log and re-raisetry: critical_operation()except Exception as e: print(f"Critical error: {e}") raise # Let the error propagate