项目文件夹

文件
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

222 行
5.8 KiB
Markdown

# 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