Skip to content
Back to skills

622 Exception Handling 48818dda

ASecurity

The news API module now uses a structured exception handling approach instead of returning error dictionaries. This provides better error handling, cleaner code, and consistent API responses.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
devopspythonflasktestingapidatabase

Works with

  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 622-exception_handling_48818dda --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 622 Exception Handling 48818dda?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 622 Exception Handling 48818dda
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-622-exception-handling-48818dda/badge)](https://www.skillsdirectory.com/skills/tools-only-622-exception-handling-48818dda)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# News API Exception Handling

## Overview

The news API module now uses a structured exception handling approach instead of returning error dictionaries. This provides better error handling, cleaner code, and consistent API responses.

## Exception Hierarchy

All news API exceptions inherit from `NewsAPIException`, which provides:
- Human-readable error messages
- HTTP status codes
- Machine-readable error codes
- Optional additional details

```python
from local_deep_research.news.exceptions import NewsAPIException

class NewsAPIException(Exception):
    def __init__(self, message: str, status_code: int = 500,
                 error_code: Optional[str] = None,
                 details: Optional[Dict[str, Any]] = None)
```

## Available Exceptions

### InvalidLimitException
- **Status Code**: 400
- **Error Code**: `INVALID_LIMIT`
- **Usage**: When an invalid limit parameter is provided
- **Example**:
```python
if limit < 1:
    raise InvalidLimitException(limit)
```

### SubscriptionNotFoundException
- **Status Code**: 404
- **Error Code**: `SUBSCRIPTION_NOT_FOUND`
- **Usage**: When a requested subscription doesn't exist
- **Example**:
```python
if not subscription:
    raise SubscriptionNotFoundException(subscription_id)
```

### SubscriptionCreationException
- **Status Code**: 500
- **Error Code**: `SUBSCRIPTION_CREATE_FAILED`
- **Usage**: When subscription creation fails
- **Example**:
```python
except Exception as e:
    raise SubscriptionCreationException(str(e), {"query": query})
```

### SubscriptionUpdateException
- **Status Code**: 500
- **Error Code**: `SUBSCRIPTION_UPDATE_FAILED`
- **Usage**: When subscription update fails

### SubscriptionDeletionException
- **Status Code**: 500
- **Error Code**: `SUBSCRIPTION_DELETE_FAILED`
- **Usage**: When subscription deletion fails

### DatabaseAccessException
- **Status Code**: 500
- **Error Code**: `DATABASE_ERROR`
- **Usage**: When database operations fail
- **Example**:
```python
except Exception as e:
    raise DatabaseAccessException("operation_name", str(e))
```

### NewsFeedGenerationException
- **Status Code**: 500
- **Error Code**: `FEED_GENERATION_FAILED`
- **Usage**: When news feed generation fails

### ResearchProcessingException
- **Status Code**: 500
- **Error Code**: `RESEARCH_PROCESSING_FAILED`
- **Usage**: When processing research items fails

### NotImplementedException
- **Status Code**: 501
- **Error Code**: `NOT_IMPLEMENTED`
- **Usage**: For features not yet implemented
- **Example**:
```python
raise NotImplementedException("feature_name")
```

### InvalidParameterException
- **Status Code**: 400
- **Error Code**: `INVALID_PARAMETER`
- **Usage**: When invalid parameters are provided

### SchedulerNotificationException
- **Status Code**: 500
- **Error Code**: `SCHEDULER_NOTIFICATION_FAILED`
- **Usage**: When scheduler notification fails (non-critical)

## Flask Integration

### Error Handlers

The Flask application automatically handles `NewsAPIException` and its subclasses:

```python
@app.errorhandler(NewsAPIException)
def handle_news_api_exception(error):
    return jsonify(error.to_dict()), error.status_code
```

### Response Format

All exceptions are converted to consistent JSON responses:

```json
{
    "error": "Human-readable error message",
    "error_code": "MACHINE_READABLE_CODE",
    "status_code": 400,
    "details": {
        "additional": "context",
        "if": "available"
    }
}
```

## Migration Guide

### Before (Error Dictionaries)

```python
def get_news_feed(limit):
    if limit < 1:
        return {
            "error": "Limit must be at least 1",
            "news_items": []
        }

    try:
        # ... code ...
    except Exception as e:
        logger.exception("Error getting news feed")
        return {"error": str(e), "news_items": []}
```

### After (Exceptions)

```python
def get_news_feed(limit):
    if limit < 1:
        raise InvalidLimitException(limit)

    try:
        # ... code ...
    except NewsAPIException:
        raise  # Re-raise our custom exceptions
    except Exception as e:
        logger.exception("Error getting news feed")
        raise NewsFeedGenerationException(str(e))
```

## Benefits

1. **Cleaner Code**: Functions focus on their primary logic without error response formatting
2. **Consistent Error Handling**: All errors follow the same format
3. **Better Testing**: Easier to test exception cases with pytest.raises
4. **Type Safety**: IDEs can better understand return types
5. **Centralized Logging**: Error logging can be handled in one place
6. **HTTP Status Codes**: Proper HTTP status codes are automatically set

## Testing

Test exception handling using pytest:

```python
import pytest
from local_deep_research.news.exceptions import InvalidLimitException

def test_invalid_limit():
    with pytest.raises(InvalidLimitException) as exc_info:
        news_api.get_news_feed(limit=-1)

    assert exc_info.value.status_code == 400
    assert exc_info.value.details["provided_limit"] == -1
```

## Best Practices

1. **Always catch and re-raise NewsAPIException subclasses**:
```python
except NewsAPIException:
    raise  # Let Flask handle it
except Exception as e:
    # Convert to appropriate NewsAPIException
    raise DatabaseAccessException("operation", str(e))
```

2. **Include relevant details**:
```python
raise SubscriptionCreationException(
    "Database constraint violated",
    details={"query": query, "type": subscription_type}
)
```

3. **Use appropriate exception types**: Choose the most specific exception that matches the error condition

4. **Log before raising**: For unexpected errors, log the full exception before converting to NewsAPIException

## Future Improvements

- Add retry logic for transient errors
- Implement exception metrics/monitoring
- Add internationalization support for error messages
- Create exception middleware for advanced error handling

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.