diff --git a/relay/application.py b/relay/application.py index ad9fb96..5bdc04f 100644 --- a/relay/application.py +++ b/relay/application.py @@ -12,6 +12,7 @@ from aiohttp.web import HTTPException, StaticResource from aiohttp_swagger import setup_swagger from aputils.signer import Signer from base64 import b64encode +from blib import HttpError from bsql import Database from collections.abc import Awaitable, Callable from datetime import datetime, timedelta @@ -26,8 +27,7 @@ from .config import Config from .database import Connection, get_database from .database.schema import Instance from .http_client import HttpClient -from .misc import HttpError, Message, Response, check_open_port, get_resource -from .misc import JSON_PATHS, TOKEN_PATHS +from .misc import JSON_PATHS, TOKEN_PATHS, Message, Response, check_open_port, get_resource from .template import Template from .views import VIEWS from .views.api import handle_api_path @@ -296,7 +296,7 @@ def format_error(request: web.Request, error: HttpError) -> Response: app: Application = request.app # type: ignore[assignment] if request.path.startswith(JSON_PATHS) or 'json' in request.headers.get('accept', ''): - return Response.new({'error': error.body}, error.status, ctype = 'json') + return Response.new({'error': error.message}, error.status, ctype = 'json') else: body = app.template.render('page/error.haml', request, e = error) @@ -338,21 +338,21 @@ async def handle_response_headers( except HttpError as e: resp = format_error(request, e) - except HTTPException as ae: - if ae.status == 404: + except HTTPException as e: + if e.status == 404: try: - text = (ae.text or "").split(":")[1].strip() + text = (e.text or "").split(":")[1].strip() except IndexError: - text = ae.text or "" + text = e.text or "" - resp = format_error(request, HttpError(ae.status, text)) + resp = format_error(request, HttpError(e.status, text)) else: raise - except Exception as e: - resp = format_error(request, HttpError(500, f'{type(e).__name__}: {str(e)}')) + except Exception: + resp = format_error(request, HttpError(500, 'Internal server error')) traceback.print_exc() resp.headers['Server'] = 'ActivityRelay' diff --git a/relay/frontend/page/error.haml b/relay/frontend/page/error.haml index 4d4bf95..23a8935 100644 --- a/relay/frontend/page/error.haml +++ b/relay/frontend/page/error.haml @@ -4,4 +4,4 @@ -block content .section.error .title << HTTP Error {{e.status}} - .body -> =e.body + .body -> =e.message diff --git a/relay/misc.py b/relay/misc.py index cb35339..aa44956 100644 --- a/relay/misc.py +++ b/relay/misc.py @@ -134,17 +134,6 @@ def get_resource(path: str) -> Path: return Path(str(pkgfiles('relay'))).joinpath(path) -class HttpError(Exception): - def __init__(self, - status: int, - body: str) -> None: - - self.body: str = body - self.status: int = status - - Exception.__init__(self, f"HTTP Error {status}: {body}") - - class JsonEncoder(json.JSONEncoder): def default(self, o: Any) -> str: if isinstance(o, datetime): diff --git a/relay/views/activitypub.py b/relay/views/activitypub.py index aa672f2..4551c88 100644 --- a/relay/views/activitypub.py +++ b/relay/views/activitypub.py @@ -2,12 +2,13 @@ import aputils import traceback from aiohttp.web import Request +from blib import HttpError from .base import View, register_route from .. import logger as logging from ..database import schema -from ..misc import HttpError, Message, Response +from ..misc import Message, Response from ..processors import run_processor @@ -93,15 +94,19 @@ class ActorView(View): try: self.actor = await self.client.get(self.signature.keyid, True, Message) - except Exception: + except HttpError: # ld signatures aren't handled atm, so just ignore it if self.message.type == 'Delete': logging.verbose('Instance sent a delete which cannot be handled') raise HttpError(202, '') - logging.verbose(f'Failed to fetch actor: {self.signature.keyid}') + logging.verbose('Failed to fetch actor: %s', self.signature.keyid) raise HttpError(400, 'failed to fetch actor') + except Exception: + traceback.print_exc() + raise HttpError(500, 'unexpected error when fetching actor') + try: self.signer = self.actor.signer diff --git a/relay/views/api.py b/relay/views/api.py index 428aa63..e7cb5fb 100644 --- a/relay/views/api.py +++ b/relay/views/api.py @@ -2,7 +2,7 @@ import traceback from aiohttp.web import Request, middleware from argon2.exceptions import VerifyMismatchError -from blib import convert_to_boolean +from blib import HttpError, convert_to_boolean from collections.abc import Awaitable, Callable, Sequence from urllib.parse import urlparse @@ -10,7 +10,7 @@ from .base import View, register_route from .. import __version__ from ..database import ConfigData, schema -from ..misc import HttpError, Message, Response, boolean +from ..misc import Message, Response, boolean DEFAULT_REDIRECT: str = 'urn:ietf:wg:oauth:2.0:oob' @@ -324,7 +324,7 @@ class Inbox(View): except Exception: traceback.print_exc() - raise HttpError(500, 'Failed to fetch actor') + raise HttpError(500, 'Failed to fetch actor') from None data['inbox'] = actor_data.shared_inbox @@ -396,7 +396,7 @@ class RequestView(View): instance = conn.put_request_response(data['domain'], boolean(data['accept'])) except KeyError: - raise HttpError(404, 'Request not found') + raise HttpError(404, 'Request not found') from None message = Message.new_response( host = self.config.domain, diff --git a/relay/views/base.py b/relay/views/base.py index 1b2d405..624ed9d 100644 --- a/relay/views/base.py +++ b/relay/views/base.py @@ -3,6 +3,7 @@ from __future__ import annotations from aiohttp.abc import AbstractView from aiohttp.hdrs import METH_ALL as METHODS from aiohttp.web import Request +from blib import HttpError from bsql import Database from collections.abc import Awaitable, Callable, Generator, Sequence, Mapping from functools import cached_property @@ -13,7 +14,7 @@ from ..cache import Cache from ..config import Config from ..database import Connection from ..http_client import HttpClient -from ..misc import HttpError, Response, get_app +from ..misc import Response, get_app if TYPE_CHECKING: from typing import Self @@ -137,7 +138,7 @@ class View(AbstractView): data[key] = post_data[key] except KeyError as e: - raise HttpError(400, f'Missing {str(e)} pararmeter') + raise HttpError(400, f'Missing {str(e)} pararmeter') from None for key in optional: data[key] = post_data.get(key) # type: ignore[assignment]