Forráskód Böngészése

Stop parsing InternalErrors

signald's InternalError exception is meant to be a fallback when unexpected
behavior occurs. We were parsing it out in several places which have now been
converted into proper protocol errors on the signald side

Note that this requires signald 0.16.1-78-d88f5798 or newer
finn 3 éve
szülő
commit
faeb853fe7

+ 12 - 2
mausignald/errors.py

@@ -53,7 +53,11 @@ class CaptchaRequired(ResponseError):
     pass
 
 
-class AuthorizationFailedException(ResponseError):
+class AuthorizationFailedError(ResponseError):
+    pass
+
+
+class ScanTimeoutError(ResponseError):
     pass
 
 
@@ -70,6 +74,11 @@ class RequestValidationFailure(ResponseError):
 
 
 class InternalError(ResponseError):
+    """
+    If you find yourself using this, please file an issue against signald. We want to make
+    explicit error types at the protocol for anything a client might normally expect.
+    """
+
     def __init__(self, data: dict[str, Any]) -> None:
         exceptions = data.get("exceptions", [])
         self.exceptions = exceptions
@@ -90,9 +99,10 @@ response_error_types = {
     "RequestValidationFailure": RequestValidationFailure,
     "UnknownIdentityKey": UnknownIdentityKey,
     "CaptchaRequired": CaptchaRequired,
-    "AuthorizationFailedException": AuthorizationFailedException,
     "InternalError": InternalError,
     "AttachmentTooLargeError": AttachmentTooLargeError,
+    "AuthorizationFailedError": AuthorizationFailedError,
+    "ScanTimeoutError": ScanTimeoutError,
     # TODO add rest from https://gitlab.com/signald/signald/-/tree/main/src/main/java/io/finn/signald/exceptions
 }
 

+ 2 - 5
mausignald/signald.py

@@ -11,7 +11,7 @@ import asyncio
 
 from mautrix.util.logging import TraceLogger
 
-from .errors import InternalError, RPCError, UnexpectedResponse
+from .errors import AuthorizationFailedError, InternalError, RPCError, UnexpectedResponse
 from .rpc import CONNECT_EVENT, DISCONNECT_EVENT, SignaldRPCClient
 from .types import (
     Account,
@@ -112,10 +112,7 @@ class SignaldClient(SignaldRPCClient):
         except RPCError as e:
             self.log.debug("Failed to subscribe to %s: %s", username, e)
             state = WebsocketConnectionState.DISCONNECTED
-            auth_failed = (
-                "org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException"
-            )
-            if isinstance(e, InternalError) and auth_failed in e.data.get("exceptions", []):
+            if isinstance(e, AuthorizationFailedError):
                 state = WebsocketConnectionState.AUTHENTICATION_FAILED
             evt = WebsocketConnectionStateChangeEvent(state=state, account=username)
             await self._run_event_handler(evt)

+ 2 - 2
mautrix_signal/commands/auth.py

@@ -16,7 +16,7 @@
 from typing import Union
 import io
 
-from mausignald.errors import AuthorizationFailedException, TimeoutException, UnexpectedResponse
+from mausignald.errors import AuthorizationFailedError, TimeoutException, UnexpectedResponse
 from mautrix.appservice import IntentAPI
 from mautrix.bridge.commands import HelpSection, command_handler
 from mautrix.types import EventID, ImageInfo, MediaMessageEventContent, MessageType
@@ -202,6 +202,6 @@ async def remove_linked_device(evt: CommandEvent) -> EventID:
     device_id = int(evt.args[0])
     try:
         await evt.bridge.signal.remove_linked_device(evt.sender.username, device_id)
-    except AuthorizationFailedException as e:
+    except AuthorizationFailedError as e:
         return await evt.reply(f"{e} Only the primary device can remove linked devices.")
     return await evt.reply("Device removed")

+ 2 - 5
mautrix_signal/user.py

@@ -21,7 +21,7 @@ from datetime import datetime
 from uuid import UUID
 import asyncio
 
-from mausignald.errors import ResponseError
+from mausignald.errors import AuthorizationFailedError, ResponseError
 from mausignald.types import (
     Account,
     Address,
@@ -148,10 +148,7 @@ class User(DBUser, BaseUser):
         return [state]
 
     async def handle_auth_failure(self, e: Exception) -> None:
-        auth_failed = (
-            "org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException"
-        )
-        if isinstance(e, ResponseError) and auth_failed in e.data.get("exceptions", []):
+        if isinstance(e, AuthorizationFailedError):
             await self.push_bridge_state(BridgeStateEvent.BAD_CREDENTIALS, error=str(e))
 
     async def get_puppet(self) -> pu.Puppet | None:

+ 7 - 7
mautrix_signal/web/provisioning_api.py

@@ -22,7 +22,7 @@ import logging
 
 from aiohttp import web
 
-from mausignald.errors import InternalError, TimeoutException
+from mausignald.errors import InternalError, ScanTimeoutError, TimeoutException
 from mausignald.types import Account, Address
 from mautrix.types import UserID
 from mautrix.util.logging import TraceLogger
@@ -176,12 +176,12 @@ class ProvisioningAPI:
             raise web.HTTPBadRequest(
                 text='{"error": "Signal linking timed out"}', headers=self._headers
             )
-        except InternalError as ie:
-            if "java.io.IOException" in ie.exceptions:
-                raise web.HTTPBadRequest(
-                    text='{"error": "Signald websocket disconnected before linking finished"}',
-                    headers=self._headers,
-                )
+        except ScanTimeoutError:
+            raise web.HTTPBadRequest(
+                text='{"error": "Signald websocket disconnected before linking finished"}',
+                headers=self._headers,
+            )
+        except InternalError:
             raise web.HTTPInternalServerError(
                 text='{"error": "Fatal error in Signal linking"}', headers=self._headers
             )