Catch any nio.ErrorResponse to raise MatrixErrors
This commit is contained in:
		
							
								
								
									
										1
									
								
								TODO.md
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								TODO.md
									
									
									
									
									
								
							@@ -48,6 +48,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## Issues
 | 
					## Issues
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Room pane can't make thin enough when zoomed
 | 
				
			||||||
- `EventImage`s for `m.image` sometimes appear broken, can be made normal
 | 
					- `EventImage`s for `m.image` sometimes appear broken, can be made normal
 | 
				
			||||||
  by switching to another room and coming back
 | 
					  by switching to another room and coming back
 | 
				
			||||||
- First sent message in E2E room is sometimes undecryptable
 | 
					- First sent message in E2E room is sometimes undecryptable
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -220,9 +220,6 @@ class Backend:
 | 
				
			|||||||
            client   = await self.get_any_client()
 | 
					            client   = await self.get_any_client()
 | 
				
			||||||
            response = await client.get_profile(user_id)
 | 
					            response = await client.get_profile(user_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if isinstance(response, nio.ProfileGetError):
 | 
					 | 
				
			||||||
                raise MatrixError.from_nio(response)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            self.profile_cache[user_id] = response
 | 
					            self.profile_cache[user_id] = response
 | 
				
			||||||
            return response
 | 
					            return response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -234,12 +231,7 @@ class Backend:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        args   = (server_name, media_id, width, height)
 | 
					        args   = (server_name, media_id, width, height)
 | 
				
			||||||
        client = await self.get_any_client()
 | 
					        client = await self.get_any_client()
 | 
				
			||||||
        response = await client.thumbnail(*args)
 | 
					        return await client.thumbnail(*args)
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if isinstance(response, nio.ThumbnailError):
 | 
					 | 
				
			||||||
            raise MatrixError.from_nio(response)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return response
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def download(
 | 
					    async def download(
 | 
				
			||||||
@@ -248,12 +240,7 @@ class Backend:
 | 
				
			|||||||
        """Return the content of a matrix media."""
 | 
					        """Return the content of a matrix media."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        client = await self.get_any_client()
 | 
					        client = await self.get_any_client()
 | 
				
			||||||
        response = await client.download(server_name, media_id)
 | 
					        return await client.download(server_name, media_id)
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if isinstance(response, nio.DownloadError):
 | 
					 | 
				
			||||||
            raise MatrixError.from_nio(response)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return response
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # General functions
 | 
					    # General functions
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -71,11 +71,6 @@ class MatrixTooLarge(MatrixError):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Client errors
 | 
					# Client errors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@dataclass
 | 
					 | 
				
			||||||
class UserNotFound(Exception):
 | 
					 | 
				
			||||||
    user_id: str = field()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@dataclass
 | 
					@dataclass
 | 
				
			||||||
class InvalidUserId(Exception):
 | 
					class InvalidUserId(Exception):
 | 
				
			||||||
    user_id: str = field()
 | 
					    user_id: str = field()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,11 +28,10 @@ import nio
 | 
				
			|||||||
from nio.crypto import AsyncDataT as UploadData
 | 
					from nio.crypto import AsyncDataT as UploadData
 | 
				
			||||||
from nio.crypto import async_generator_from_data
 | 
					from nio.crypto import async_generator_from_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from . import __app_name__, __display_name__
 | 
					from . import __app_name__, __display_name__, utils
 | 
				
			||||||
from . import utils
 | 
					 | 
				
			||||||
from .errors import (
 | 
					from .errors import (
 | 
				
			||||||
    BadMimeType, InvalidUserId, InvalidUserInContext, MatrixError,
 | 
					    BadMimeType, InvalidUserId, InvalidUserInContext, MatrixError,
 | 
				
			||||||
    UneededThumbnail, UserNotFound,
 | 
					    MatrixNotFound, UneededThumbnail,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from .html_markdown import HTML_PROCESSOR as HTML
 | 
					from .html_markdown import HTML_PROCESSOR as HTML
 | 
				
			||||||
from .models.items import (
 | 
					from .models.items import (
 | 
				
			||||||
@@ -131,6 +130,22 @@ class MatrixClient(nio.AsyncClient):
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def _send(self, *args, **kwargs) -> nio.Response:
 | 
				
			||||||
 | 
					        """Raise a `MatrixError` subclass for any `nio.ErrorResponse`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        This function is called by `nio.AsyncClient`'s methods to send
 | 
				
			||||||
 | 
					        requests to the server. Return normal responses, but catch any
 | 
				
			||||||
 | 
					        `ErrorResponse` to turn them into `MatrixError` exceptions we raise.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        response = await super()._send(*args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if isinstance(response, nio.ErrorResponse):
 | 
				
			||||||
 | 
					            raise MatrixError.from_nio(response)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def default_device_name(self) -> str:
 | 
					    def default_device_name(self) -> str:
 | 
				
			||||||
        """Device name to set at login if the user hasn't set a custom one."""
 | 
					        """Device name to set at login if the user hasn't set a custom one."""
 | 
				
			||||||
@@ -143,13 +158,7 @@ class MatrixClient(nio.AsyncClient):
 | 
				
			|||||||
    async def login(self, password: str, device_name: str = "") -> None:
 | 
					    async def login(self, password: str, device_name: str = "") -> None:
 | 
				
			||||||
        """Login to the server using the account's password."""
 | 
					        """Login to the server using the account's password."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        response = await super().login(
 | 
					        await super().login(password, device_name or self.default_device_name)
 | 
				
			||||||
            password, device_name or self.default_device_name,
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if isinstance(response, nio.LoginError):
 | 
					 | 
				
			||||||
            raise MatrixError.from_nio(response)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        asyncio.ensure_future(self._start())
 | 
					        asyncio.ensure_future(self._start())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -221,7 +230,7 @@ class MatrixClient(nio.AsyncClient):
 | 
				
			|||||||
                break  # task cancelled
 | 
					                break  # task cancelled
 | 
				
			||||||
            except Exception:
 | 
					            except Exception:
 | 
				
			||||||
                trace = traceback.format_exc().rstrip()
 | 
					                trace = traceback.format_exc().rstrip()
 | 
				
			||||||
                log.error("Exception during sync, will restart:\n%s", trace)
 | 
					                log.error("Exception during sync, restart in 2s:\n%s", trace)
 | 
				
			||||||
                await asyncio.sleep(2)
 | 
					                await asyncio.sleep(2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -520,16 +529,13 @@ class MatrixClient(nio.AsyncClient):
 | 
				
			|||||||
        """Send a message event with `content` dict to a room."""
 | 
					        """Send a message event with `content` dict to a room."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        async with self.backend.send_locks[room_id]:
 | 
					        async with self.backend.send_locks[room_id]:
 | 
				
			||||||
            response = await self.room_send(
 | 
					            await self.room_send(
 | 
				
			||||||
                room_id                   = room_id,
 | 
					                room_id                   = room_id,
 | 
				
			||||||
                message_type              = "m.room.message",
 | 
					                message_type              = "m.room.message",
 | 
				
			||||||
                content                   = content,
 | 
					                content                   = content,
 | 
				
			||||||
                ignore_unverified_devices = True,
 | 
					                ignore_unverified_devices = True,
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if isinstance(response, nio.RoomSendError):
 | 
					 | 
				
			||||||
            raise MatrixError.from_nio(response)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def load_past_events(self, room_id: str) -> bool:
 | 
					    async def load_past_events(self, room_id: str) -> bool:
 | 
				
			||||||
        """Ask the server for 100 previous events  of the room.
 | 
					        """Ask the server for 100 previous events  of the room.
 | 
				
			||||||
@@ -557,9 +563,6 @@ class MatrixClient(nio.AsyncClient):
 | 
				
			|||||||
            limit   = 100 if room_id in self.loaded_once_rooms else 25,
 | 
					            limit   = 100 if room_id in self.loaded_once_rooms else 25,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if isinstance(response, nio.RoomMessagesError):
 | 
					 | 
				
			||||||
            raise MatrixError.from_nio(response)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.loaded_once_rooms.add(room_id)
 | 
					        self.loaded_once_rooms.add(room_id)
 | 
				
			||||||
        more_to_load = True
 | 
					        more_to_load = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -620,21 +623,16 @@ class MatrixClient(nio.AsyncClient):
 | 
				
			|||||||
        if not self.user_id_regex.match(invite):
 | 
					        if not self.user_id_regex.match(invite):
 | 
				
			||||||
            raise InvalidUserId(invite)
 | 
					            raise InvalidUserId(invite)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if isinstance(await self.get_profile(invite), nio.ProfileGetError):
 | 
					        # Raise MatrixNotFound if profile doesn't exist
 | 
				
			||||||
            raise UserNotFound(invite)
 | 
					        await self.get_profile(invite)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        response = await super().room_create(
 | 
					        return await super().room_create(
 | 
				
			||||||
            invite        = [invite],
 | 
					            invite        = [invite],
 | 
				
			||||||
            is_direct     = True,
 | 
					            is_direct     = True,
 | 
				
			||||||
            visibility    = nio.RoomVisibility.private,
 | 
					            visibility    = nio.RoomVisibility.private,
 | 
				
			||||||
            initial_state =
 | 
					            initial_state =
 | 
				
			||||||
                [nio.EnableEncryptionBuilder().as_dict()] if encrypt else [],
 | 
					                [nio.EnableEncryptionBuilder().as_dict()] if encrypt else [],
 | 
				
			||||||
        )
 | 
					        ).room_id
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if isinstance(response, nio.RoomCreateError):
 | 
					 | 
				
			||||||
            raise MatrixError.from_nio(response)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return response.room_id
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def new_group_chat(
 | 
					    async def new_group_chat(
 | 
				
			||||||
@@ -647,7 +645,7 @@ class MatrixClient(nio.AsyncClient):
 | 
				
			|||||||
    ) -> str:
 | 
					    ) -> str:
 | 
				
			||||||
        """Create a new matrix room with the purpose of being a group chat."""
 | 
					        """Create a new matrix room with the purpose of being a group chat."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        response = await super().room_create(
 | 
					        return await super().room_create(
 | 
				
			||||||
            name       = name or None,
 | 
					            name       = name or None,
 | 
				
			||||||
            topic      = topic or None,
 | 
					            topic      = topic or None,
 | 
				
			||||||
            federate   = federate,
 | 
					            federate   = federate,
 | 
				
			||||||
@@ -656,12 +654,7 @@ class MatrixClient(nio.AsyncClient):
 | 
				
			|||||||
                nio.RoomVisibility.private,
 | 
					                nio.RoomVisibility.private,
 | 
				
			||||||
            initial_state =
 | 
					            initial_state =
 | 
				
			||||||
                [nio.EnableEncryptionBuilder().as_dict()] if encrypt else [],
 | 
					                [nio.EnableEncryptionBuilder().as_dict()] if encrypt else [],
 | 
				
			||||||
        )
 | 
					        ).room_id
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if isinstance(response, nio.RoomCreateError):
 | 
					 | 
				
			||||||
            raise MatrixError.from_nio(response)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return response.room_id
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def room_join(self, alias_or_id_or_url: str) -> str:
 | 
					    async def room_join(self, alias_or_id_or_url: str) -> str:
 | 
				
			||||||
        """Join an existing matrix room."""
 | 
					        """Join an existing matrix room."""
 | 
				
			||||||
@@ -679,12 +672,7 @@ class MatrixClient(nio.AsyncClient):
 | 
				
			|||||||
        if not self.room_id_or_alias_regex.match(string):
 | 
					        if not self.room_id_or_alias_regex.match(string):
 | 
				
			||||||
            raise ValueError("Not an alias or room id")
 | 
					            raise ValueError("Not an alias or room id")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        response = await super().join(string)
 | 
					        return await super().join(string).room_id
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if isinstance(response, nio.JoinError):
 | 
					 | 
				
			||||||
            raise MatrixError.from_nio(response)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return response.room_id
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def room_forget(self, room_id: str) -> None:
 | 
					    async def room_forget(self, room_id: str) -> None:
 | 
				
			||||||
@@ -722,8 +710,10 @@ class MatrixClient(nio.AsyncClient):
 | 
				
			|||||||
            if not self.user_id_regex.match(user):
 | 
					            if not self.user_id_regex.match(user):
 | 
				
			||||||
                return InvalidUserId(user)
 | 
					                return InvalidUserId(user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if isinstance(await self.get_profile(user), nio.ProfileGetError):
 | 
					            try:
 | 
				
			||||||
                return UserNotFound(user)
 | 
					                await self.get_profile(user)
 | 
				
			||||||
 | 
					            except MatrixNotFound as err:
 | 
				
			||||||
 | 
					                return err
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return await self.room_invite(room_id, user)
 | 
					            return await self.room_invite(room_id, user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -810,9 +800,6 @@ class MatrixClient(nio.AsyncClient):
 | 
				
			|||||||
            monitor,
 | 
					            monitor,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if isinstance(response, nio.UploadError):
 | 
					 | 
				
			||||||
            raise MatrixError.from_nio(response)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return UploadReturn(response.content_uri, mime, decryption_dict)
 | 
					        return UploadReturn(response.content_uri, mime, decryption_dict)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -89,14 +89,6 @@ class NioCallbacks:
 | 
				
			|||||||
            account.first_sync_done = True
 | 
					            account.first_sync_done = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def onErrorResponse(self, resp: nio.ErrorResponse) -> None:
 | 
					 | 
				
			||||||
        # TODO: show something in the client, must be seen on login screen too
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            log.warning("%s - %s", resp, json.dumps(vars(resp), indent=4))
 | 
					 | 
				
			||||||
        except Exception:
 | 
					 | 
				
			||||||
            log.warning(repr(resp))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Event callbacks
 | 
					    # Event callbacks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def onRoomMessageText(self, room, ev) -> None:
 | 
					    async def onRoomMessageText(self, room, ev) -> None:
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user