kopia lustrzana https://github.com/bugout-dev/moonstream
Extended HTTPException and Response with error handling
rodzic
120b6a952c
commit
6ac9df74aa
|
@ -1,10 +1,11 @@
|
|||
import logging
|
||||
from typing import Awaitable, Callable, Dict, Optional
|
||||
from typing import Any, Awaitable, Callable, Dict, Optional
|
||||
|
||||
from bugout.data import BugoutUser
|
||||
from bugout.exceptions import BugoutResponseException
|
||||
from fastapi import HTTPException, Request, Response
|
||||
from starlette.background import BackgroundTask
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
from fastapi import Request, Response
|
||||
|
||||
from .reporter import reporter
|
||||
from .settings import MOONSTREAM_APPLICATION_ID, bugout_client as bc
|
||||
|
@ -12,6 +13,44 @@ from .settings import MOONSTREAM_APPLICATION_ID, bugout_client as bc
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MoonstreamResponse(Response):
|
||||
"""
|
||||
Extended Response to handle 500 Internal server errors
|
||||
and send crash reports.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
content: Any = None,
|
||||
status_code: int = 200,
|
||||
headers: dict = None,
|
||||
media_type: str = None,
|
||||
background: BackgroundTask = None,
|
||||
internal_error: Exception = None,
|
||||
):
|
||||
super().__init__(content, status_code, headers, media_type, background)
|
||||
if internal_error is not None:
|
||||
reporter.error_report(internal_error)
|
||||
|
||||
|
||||
class MoonstreamHTTPException(HTTPException):
|
||||
"""
|
||||
Extended HTTPException to handle 500 Internal server errors
|
||||
and send crash reports.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
status_code: int,
|
||||
detail: Any = None,
|
||||
headers: Optional[Dict[str, Any]] = None,
|
||||
internal_error: Exception = None,
|
||||
):
|
||||
super().__init__(status_code, detail, headers)
|
||||
if internal_error is not None:
|
||||
reporter.error_report(internal_error)
|
||||
|
||||
|
||||
class BroodAuthMiddleware(BaseHTTPMiddleware):
|
||||
"""
|
||||
Checks the authorization header on the request. If it represents a verified Brood user,
|
||||
|
@ -62,8 +101,9 @@ class BroodAuthMiddleware(BaseHTTPMiddleware):
|
|||
return Response(status_code=e.status_code, content=e.detail)
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing Brood response: {str(e)}")
|
||||
reporter.error_report(e)
|
||||
return Response(status_code=500, content="Internal server error")
|
||||
return MoonstreamResponse(
|
||||
status_code=500, content="Internal server error", internal_error=e
|
||||
)
|
||||
|
||||
request.state.user = user
|
||||
request.state.token = user_token
|
||||
|
|
|
@ -3,15 +3,14 @@ from typing import Dict, List, Optional
|
|||
|
||||
from sqlalchemy.sql.expression import true
|
||||
|
||||
from fastapi import FastAPI, Depends, Query, HTTPException
|
||||
from fastapi import FastAPI, Depends, Query
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from moonstreamdb.db import yield_db_session
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from .. import actions
|
||||
from .. import data
|
||||
from ..middleware import BroodAuthMiddleware
|
||||
from ..reporter import reporter
|
||||
from ..middleware import BroodAuthMiddleware, MoonstreamHTTPException
|
||||
from ..settings import DOCS_TARGET_PATH, ORIGINS, DOCS_PATHS
|
||||
from ..version import MOONSTREAM_VERSION
|
||||
|
||||
|
@ -74,16 +73,15 @@ async def addresses_labels_bulk_handler(
|
|||
about known addresses.
|
||||
"""
|
||||
if limit > 100:
|
||||
raise HTTPException(
|
||||
raise MoonstreamHTTPException(
|
||||
status_code=406, detail="The limit cannot exceed 100 addresses"
|
||||
)
|
||||
try:
|
||||
addresses_response = actions.get_address_labels(
|
||||
db_session=db_session, start=start, limit=limit, addresses=addresses
|
||||
)
|
||||
except Exception as err:
|
||||
logger.error(f"Unable to get info about Ethereum addresses {err}")
|
||||
reporter.error_report(err)
|
||||
raise HTTPException(status_code=500)
|
||||
except Exception as e:
|
||||
logger.error(f"Unable to get info about Ethereum addresses {e}")
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
|
||||
return addresses_response
|
||||
|
|
|
@ -5,14 +5,14 @@ import logging
|
|||
from typing import Dict, List, Optional
|
||||
|
||||
from bugout.data import BugoutResource
|
||||
from fastapi import FastAPI, HTTPException, Request, Query, Depends
|
||||
from fastapi import FastAPI, Request, Query, Depends
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from moonstreamdb import db
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
|
||||
from .. import data
|
||||
from ..middleware import BroodAuthMiddleware
|
||||
from ..middleware import BroodAuthMiddleware, MoonstreamHTTPException
|
||||
from ..providers import (
|
||||
ReceivingEventsException,
|
||||
event_providers,
|
||||
|
@ -21,7 +21,6 @@ from ..providers import (
|
|||
next_event,
|
||||
previous_event,
|
||||
)
|
||||
from ..reporter import reporter
|
||||
from ..settings import (
|
||||
DOCS_TARGET_PATH,
|
||||
MOONSTREAM_ADMIN_ACCESS_TOKEN,
|
||||
|
@ -137,12 +136,10 @@ async def stream_handler(
|
|||
)
|
||||
except ReceivingEventsException as e:
|
||||
logger.error("Error receiving events from provider")
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
except Exception as e:
|
||||
logger.error("Unable to get events")
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
|
||||
response = data.GetEventsResponse(stream_boundary=stream_boundary, events=events)
|
||||
return response
|
||||
|
@ -182,12 +179,10 @@ async def latest_events_handler(
|
|||
)
|
||||
except ReceivingEventsException as e:
|
||||
logger.error("Error receiving events from provider")
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
except Exception as e:
|
||||
logger.error("Unable to get latest events")
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
|
||||
return events
|
||||
|
||||
|
@ -239,12 +234,10 @@ async def next_event_handler(
|
|||
)
|
||||
except ReceivingEventsException as e:
|
||||
logger.error("Error receiving events from provider")
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
except Exception as e:
|
||||
logger.error("Unable to get next events")
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
|
||||
return event
|
||||
|
||||
|
@ -296,11 +289,9 @@ async def previous_event_handler(
|
|||
)
|
||||
except ReceivingEventsException as e:
|
||||
logger.error("Error receiving events from provider")
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
except Exception as e:
|
||||
logger.error("Unable to get previous events")
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
|
||||
return event
|
||||
|
|
|
@ -6,12 +6,12 @@ from typing import Dict, List, Optional
|
|||
|
||||
from bugout.data import BugoutResource, BugoutResources
|
||||
from bugout.exceptions import BugoutResponseException
|
||||
from fastapi import FastAPI, HTTPException, Request, Form
|
||||
from fastapi import FastAPI, Request, Form
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
|
||||
from ..admin import subscription_types
|
||||
from .. import data
|
||||
from ..middleware import BroodAuthMiddleware
|
||||
from ..middleware import BroodAuthMiddleware, MoonstreamHTTPException
|
||||
from ..reporter import reporter
|
||||
from ..settings import (
|
||||
DOCS_TARGET_PATH,
|
||||
|
@ -78,7 +78,7 @@ async def add_subscription_handler(
|
|||
]
|
||||
|
||||
if subscription_type_id not in available_subscription_type_ids:
|
||||
raise HTTPException(
|
||||
raise MoonstreamHTTPException(
|
||||
status_code=404,
|
||||
detail=f"Invalid subscription type: {subscription_type_id}.",
|
||||
)
|
||||
|
@ -100,10 +100,11 @@ async def add_subscription_handler(
|
|||
application_id=MOONSTREAM_APPLICATION_ID,
|
||||
resource_data=resource_data,
|
||||
)
|
||||
except BugoutResponseException as e:
|
||||
raise MoonstreamHTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating subscription resource: {str(e)}")
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
|
||||
return data.SubscriptionResourceData(
|
||||
id=str(resource.id),
|
||||
|
@ -128,11 +129,10 @@ async def delete_subscription_handler(request: Request, subscription_id: str):
|
|||
try:
|
||||
deleted_resource = bc.delete_resource(token=token, resource_id=subscription_id)
|
||||
except BugoutResponseException as e:
|
||||
raise HTTPException(status_code=e.status_code, detail=e.detail)
|
||||
raise MoonstreamHTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except Exception as e:
|
||||
logger.error(f"Error deleting subscription: {str(e)}")
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
|
||||
return data.SubscriptionResourceData(
|
||||
id=str(deleted_resource.id),
|
||||
|
@ -156,12 +156,14 @@ async def get_subscriptions_handler(request: Request) -> data.SubscriptionsListR
|
|||
}
|
||||
try:
|
||||
resources: BugoutResources = bc.list_resources(token=token, params=params)
|
||||
except BugoutResponseException as e:
|
||||
raise MoonstreamHTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"Error listing subscriptions for user ({request.user.id}) with token ({request.state.token}), error: {str(e)}"
|
||||
)
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
|
||||
return data.SubscriptionsListResponse(
|
||||
subscriptions=[
|
||||
|
@ -211,11 +213,10 @@ async def update_subscriptions_handler(
|
|||
).dict(),
|
||||
)
|
||||
except BugoutResponseException as e:
|
||||
raise HTTPException(status_code=e.status_code, detail=e.detail)
|
||||
raise MoonstreamHTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting user subscriptions: {str(e)}")
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
|
||||
return data.SubscriptionResourceData(
|
||||
id=str(resource.id),
|
||||
|
@ -241,9 +242,10 @@ async def list_subscription_types() -> data.SubscriptionTypesListResponse:
|
|||
data.SubscriptionTypeResourceData.validate(resource.resource_data)
|
||||
for resource in response.resources
|
||||
]
|
||||
except BugoutResponseException as e:
|
||||
raise MoonstreamHTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except Exception as e:
|
||||
logger.error(f"Error reading subscription types from Brood API: {str(e)}")
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
|
||||
return data.SubscriptionTypesListResponse(subscription_types=results)
|
||||
|
|
|
@ -7,16 +7,10 @@ import uuid
|
|||
|
||||
from bugout.data import BugoutToken, BugoutUser
|
||||
from bugout.exceptions import BugoutResponseException
|
||||
from fastapi import (
|
||||
FastAPI,
|
||||
Form,
|
||||
HTTPException,
|
||||
Request,
|
||||
)
|
||||
from fastapi import FastAPI, Form, Request
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
|
||||
from ..middleware import BroodAuthMiddleware
|
||||
from ..reporter import reporter
|
||||
from ..middleware import BroodAuthMiddleware, MoonstreamHTTPException
|
||||
from ..settings import (
|
||||
MOONSTREAM_APPLICATION_ID,
|
||||
DOCS_TARGET_PATH,
|
||||
|
@ -76,10 +70,9 @@ async def create_user_handler(
|
|||
application_id=MOONSTREAM_APPLICATION_ID,
|
||||
)
|
||||
except BugoutResponseException as e:
|
||||
raise HTTPException(status_code=e.status_code, detail=e.detail)
|
||||
raise MoonstreamHTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except Exception as e:
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
return user
|
||||
|
||||
|
||||
|
@ -94,10 +87,9 @@ async def restore_password_handler(email: str = Form(...)) -> Dict[str, Any]:
|
|||
try:
|
||||
response = bc.restore_password(email=email)
|
||||
except BugoutResponseException as e:
|
||||
raise HTTPException(status_code=e.status_code, detail=e.detail)
|
||||
raise MoonstreamHTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except Exception as e:
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
return response
|
||||
|
||||
|
||||
|
@ -108,10 +100,9 @@ async def reset_password_handler(
|
|||
try:
|
||||
response = bc.reset_password(reset_id=reset_id, new_password=new_password)
|
||||
except BugoutResponseException as e:
|
||||
raise HTTPException(status_code=e.status_code, detail=e.detail)
|
||||
raise MoonstreamHTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except Exception as e:
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
return response
|
||||
|
||||
|
||||
|
@ -125,10 +116,9 @@ async def change_password_handler(
|
|||
token=token, current_password=current_password, new_password=new_password
|
||||
)
|
||||
except BugoutResponseException as e:
|
||||
raise HTTPException(status_code=e.status_code, detail=e.detail)
|
||||
raise MoonstreamHTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except Exception as e:
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
return user
|
||||
|
||||
|
||||
|
@ -141,10 +131,9 @@ async def delete_user_handler(
|
|||
try:
|
||||
user = bc.delete_user(token=token, user_id=user.id, password=password)
|
||||
except BugoutResponseException as e:
|
||||
raise HTTPException(status_code=e.status_code, detail=e.detail)
|
||||
raise MoonstreamHTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except Exception as e:
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
return user
|
||||
|
||||
|
||||
|
@ -159,12 +148,11 @@ async def login_handler(
|
|||
application_id=MOONSTREAM_APPLICATION_ID,
|
||||
)
|
||||
except BugoutResponseException as e:
|
||||
raise HTTPException(
|
||||
raise MoonstreamHTTPException(
|
||||
status_code=e.status_code, detail=f"Error from Brood API: {e.detail}"
|
||||
)
|
||||
except Exception as e:
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
return token
|
||||
|
||||
|
||||
|
@ -174,8 +162,7 @@ async def logout_handler(request: Request) -> uuid.UUID:
|
|||
try:
|
||||
token_id: uuid.UUID = bc.revoke_token(token=token)
|
||||
except BugoutResponseException as e:
|
||||
raise HTTPException(status_code=e.status_code, detail=e.detail)
|
||||
raise MoonstreamHTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except Exception as e:
|
||||
reporter.error_report(e)
|
||||
raise HTTPException(status_code=500)
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
return token_id
|
||||
|
|
|
@ -29,5 +29,6 @@ toml==0.10.2
|
|||
tomli==1.0.4
|
||||
types-python-dateutil==0.1.6
|
||||
typing-extensions==3.10.0.0
|
||||
types-requests==2.25.6
|
||||
urllib3==1.26.6
|
||||
uvicorn==0.14.0
|
||||
|
|
|
@ -18,6 +18,7 @@ setup(
|
|||
"python-dateutil",
|
||||
"uvicorn",
|
||||
"types-python-dateutil",
|
||||
"types-requests",
|
||||
],
|
||||
extras_require={
|
||||
"dev": ["black", "mypy"],
|
||||
|
|
Ładowanie…
Reference in New Issue