Supprimer Rendre public Rendre privé Add tags Delete tags
  Ajouter un tag   Annuler
  Supprimer le tag   Annuler
  • • DevOps notes •
  •  
  • Tags
  • Connexion

Custom Exceptions: Tailoring Error Signals/shaare/hTTdng

  • python
  • python

Custom Exceptions: Tailoring Error Signals

  • Built-in exceptions are great, but often too generic for application-specific failures.
  • A custom exception like ServiceConnectionError immediately conveys context compared to a plain Exception.
  • Defining a base exception class groups related errors; subclasses add specificity for targeted handling.
  • Catching except BaseError: handles all related issues, while except SpecificError: addresses one case precisely.

Simple Custom Exceptions (Inheritance)

  • Create a new exception by subclassing Exception or another exception class.
  • Using pass is enough when no extra logic or attributes are needed.
  • Catch the base class (AutomationError) to handle any related subclass errors in one block.
  • Use subclasses (FileProcessingError, APICallError) when context-specific handling is required.
class AutomationError(Exception):
    """Base for all automation script errors."""
    pass

class FileProcessingError(AutomationError):
    """Error during file processing stage."""
    pass

class APICallError(AutomationError):
    """Error during an external API call."""
    pass

def process_file(filepath):
    raise FileProcessingError(f"Failed to process file at path: {filepath}")

try:
    process_file("nonexistent.csv")
except FileProcessingError as e:
    print(f"File error: {e}")
except AutomationError:
    print("Other automation error occurred.")

Adding Context with __init__

  • Override __init__ in your exception class to capture context (e.g., filename, invalid value).
  • Store custom attributes on self and build a clear message passed to super().__init__().
  • Inherit from a built-in exception (ValueError) when semantics align, allowing broad catches.
  • Attribute access (e.key_name) provides extra debugging info in handlers.
class ConfigValueError(ValueError):
    """Raised when a config value is invalid."""
    def __init__(self, key_name, invalid_value, message="Invalid configuration value."):
        self.key_name = key_name
        self.invalid_value = invalid_value
        full_message = f"{message} for key '{key_name}': received '{invalid_value}'"
        super().__init__(full_message)

try:
    raise ConfigValueError("timeout", -5, message="Timeout cannot be negative")
except ConfigValueError as e:
    print(f"{e}")
    print(f"   -> key: {e.key_name}")
    print(f"   -> value: {e.invalid_value}")

Raising and Catching Enhanced Custom Exceptions

  • Raise custom exceptions by instantiating them with relevant arguments: raise MyError(arg1, arg2).
  • In except blocks, catch specific exceptions and access their attributes for tailored recovery or logging.
  • Fallback except BaseError: catches any related subclass if no more specific handler exists.
class DeploymentError(Exception):
    """Base class for deployment-related errors."""
    pass

class InvalidEnvironmentError(DeploymentError):
    """Raised when environment is invalid."""
    def __init__(self, env_name, allowed_envs):
        self.env_name = env_name
        self.allowed_envs = allowed_envs
        super().__init__(f"Invalid environment '{env_name}'. Allowed values: {allowed_envs}")

class PackageMissingError(DeploymentError):
    """Raised when required packages are missing."""
    def __init__(self, package_name, host):
        self.package_name = package_name
        self.host = host
        super().__init__(f"Package '{package_name}' is missing on host {host}.")

def deploy_app(environment, package):
    allowed_envs = ["staging", "production"]

    if environment not in allowed_envs:
        raise InvalidEnvironmentError(environment, allowed_envs)

    if environment == "production" and package == "critical-lib":
        raise PackageMissingError(package, f"server-{environment}")

    print(f"Deployment to {environment} with package {package} succeeded.")

for env, pkg in [("dev", "tool"), ("production", "critical-lib"), ("staging", "tool")]:
    try:
        deploy_app(env, pkg)
    except DeploymentError as e:
        print(e)
4 months ago Permalien
cluster icon
  • Python Modules and the import System : Python Modules and the import System What is a Module? A module in Python corresponds directly to a single file containing Python code. The module's ...
  • Adding Tests to a Multi-File Project : Adding Tests to a Multi-File Project Standard Project Layout with Tests To maintain a clean and organized codebase, it is standard practice to separat...
  • Implementing Retries and Timeouts : Implementing Retries and Timeouts External services can be slow or unreliable, causing scripts to hang or fail unexpectedly. Timeouts and retries hel...
  • Python Functions Are First‑Class Citizens : Python Functions Are First‑Class Citizens In Python, functions behave like any other object (strings, ints, lists). Because they are "first‑clas...
  • Working with Environment Variables : Working with Environment Variables Environment variables are dynamic, named values provided by the operating system to running processes, enabling co...


(110)
Filtrer par liens sans tag
Replier Replier tout Déplier Déplier tout Êtes-vous sûr de vouloir supprimer ce lien ? Êtes-vous sûr de vouloir supprimer ce tag ? Le gestionnaire de marque-pages personnel, minimaliste, et sans base de données par la communauté Shaarli