ZetCode

Python os.strerror Function

Last modified April 11, 2025

This comprehensive guide explores Python's os.strerror function, which converts system error numbers to human-readable messages. We'll cover error code handling, platform differences, and practical usage examples.

Basic Definitions

The os.strerror function translates system error codes into readable strings. It's useful for interpreting errno values from system calls.

Key parameter: errno (integer error code). Returns corresponding error message string. The messages are platform-dependent and may vary between systems.

Basic Error Code Translation

The simplest use of os.strerror converts a numeric error code to its descriptive message. This helps make system errors more understandable.

basic_translation.py
import os

# Common error codes
error_codes = [1, 2, 13, 17, 24]

for code in error_codes:
    message = os.strerror(code)
    print(f"Error {code}: {message}")

# Example output on Linux:
# Error 1: Operation not permitted
# Error 2: No such file or directory
# Error 13: Permission denied
# Error 17: File exists
# Error 24: Too many open files

This example shows how numeric error codes translate to human-readable messages. The exact messages may vary between operating systems.

The function is particularly useful when working with low-level system calls that return numeric error codes.

Handling File Operation Errors

os.strerror can help explain why file operations failed by interpreting the error codes from exceptions like OSError.

file_errors.py
import os

def read_file(filename):
    try:
        with open(filename) as f:
            return f.read()
    except OSError as e:
        error_msg = os.strerror(e.errno)
        print(f"Failed to read {filename}: {error_msg}")
        return None

# Test with non-existent file
read_file("nonexistent.txt")

# Test with permission-denied file
read_file("/root/.bashrc")

This example demonstrates catching OSError and using os.strerror to get a clear explanation of what went wrong with the file operation.

The error messages help users understand whether the problem was missing files, permission issues, or other system errors.

Working with errno Constants

Python's errno module provides symbolic names for error codes, making code more readable when combined with os.strerror.

errno_constants.py
import os
import errno

def check_file_access(filename):
    try:
        with open(filename) as f:
            print(f"Successfully opened {filename}")
    except OSError as e:
        if e.errno == errno.ENOENT:
            msg = os.strerror(errno.ENOENT)
            print(f"File not found: {msg}")
        elif e.errno == errno.EACCES:
            msg = os.strerror(errno.EACCES)
            print(f"Permission denied: {msg}")
        else:
            print(f"Unknown error: {os.strerror(e.errno)}")

check_file_access("missing.txt")
check_file_access("/protected/file")

This example uses errno constants (ENOENT, EACCES) for more readable error handling, combined with os.strerror for user-friendly messages.

Symbolic constants make the code more maintainable and portable across different platforms.

Platform-Specific Error Messages

Error messages vary between operating systems. This example demonstrates how os.strerror returns different strings on different platforms.

platform_differences.py
import os
import sys

error_code = 2  # No such file or directory

print(f"Platform: {sys.platform}")
print(f"Error message: {os.strerror(error_code)}")

# Sample outputs:
# On Linux: "No such file or directory"
# On Windows: "The system cannot find the file specified"
# On macOS: "No such file or directory"

This simple script shows how the same error code (2) produces different messages on different operating systems.

When writing cross-platform code, be aware that error messages may need additional context for users on different systems.

Custom Error Handling Wrapper

We can create a helper function that combines os.strerror with exception handling for cleaner error reporting throughout an application.

error_wrapper.py
import os

def get_error_message(error):
    """Return formatted error message from exception or error code"""
    if isinstance(error, OSError):
        return os.strerror(error.errno)
    elif isinstance(error, int):
        return os.strerror(error)
    else:
        return str(error)

# Usage examples:
try:
    with open("missing.txt") as f:
        pass
except OSError as e:
    print(f"Error: {get_error_message(e)}")

# Can also use with raw error codes
print(f"Error 13: {get_error_message(13)}")

This wrapper function simplifies error message handling by accepting either exceptions or raw error codes and returning consistent string messages.

Such utilities help maintain consistent error reporting across large codebases.

Listing All System Error Messages

While not recommended for production, we can explore all known error codes and their messages on the current system.

list_all_errors.py
import os

def list_error_messages(max_code=100):
    """Display all error messages up to max_code"""
    print("System error messages:")
    print("======================")
    
    for code in range(max_code + 1):
        try:
            msg = os.strerror(code)
            print(f"{code:3d}: {msg}")
        except ValueError:
            pass  # Skip invalid error codes

list_error_messages()

# Note: The range of valid error codes varies by system
# Some codes may be undefined or have no message

This script attempts to display messages for all error codes up to a specified maximum. Not all codes will have valid messages.

The output provides insight into the error code ranges and messages supported on the current platform.

Handling Unknown Error Codes

When dealing with error codes from external sources, we need to handle cases where the code might be invalid or unknown to the system.

unknown_errors.py
import os

def safe_strerror(code):
    """Get error message or default if code is invalid"""
    try:
        return os.strerror(code)
    except (ValueError, TypeError):
        return f"Unknown error code: {code}"

# Test with valid and invalid codes
print(safe_strerror(2))      # Valid code
print(safe_strerror(9999))   # Invalid code
print(safe_strerror("abc"))  # Wrong type

# Output depends on system:
# Valid: "No such file or directory"
# Invalid: "Unknown error code: 9999"
# Wrong type: "Unknown error code: abc"

This example shows a defensive approach to error message translation that won't raise exceptions for invalid input.

The wrapper function ensures the application can gracefully handle any error code it might encounter.

Security Considerations

Best Practices

Source References

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Python tutorials.