When handling exceptions, preserve the original exception context and provide clear, actionable error information. Avoid creating new exceptions that lose important details from the original error, and replace generic error handling (like assertions) with specific, user-friendly messages.

Key practices:

Example of what NOT to do:

# Loses original exception context
except RateLimitError as e:
    raise RateLimitError(RATE_LIMIT_ERROR_MESSAGE, response=e.response, body=e.body)

# Generic assertion without clear message
assert condition or action

Example of better approach:

# Preserve context with logging
except RateLimitError as e:
    logger.error(RATE_LIMIT_ERROR_MESSAGE)
    raise  # Re-raise original exception

# Clear error message
if not (condition or action):
    raise ValueError("At least one of --condition or --action is required")
    set_exit_status(1)

This ensures that debugging information is preserved while still providing clear feedback to users about what went wrong and how to fix it.