Repository: opsdroid/opsdroid

Issue:
Log information if the matrix connector is unable to decrypt an event
This requires understanding the [matrix-nio](https://github.com/poljar/matrix-nio) library for how (if at all) this information is exposed.

The relevant section of the code is:
https://github.com/opsdroid/opsdroid/blob/3fe47d89df719e22861352fc3806d4093832c024/opsdroid/connector/matrix/connector.py#L280-L283


Discussion:

Resolving patch:
diff --git a/opsdroid/connector/matrix/connector.py b/opsdroid/connector/matrix/connector.py
--- a/opsdroid/connector/matrix/connector.py
+++ b/opsdroid/connector/matrix/connector.py
@@ -9,6 +9,7 @@
 import aiohttp
 import nio
 import nio.responses
+import nio.exceptions
 
 from opsdroid import const, events
 from opsdroid.connector import Connector, register_event
@@ -29,6 +30,7 @@
     "device_name": str,
     "device_id": str,
     "store_path": str,
+    "enable_encryption": bool,
 }
 
 __all__ = ["ConnectorMatrix"]
@@ -103,7 +105,14 @@ def __init__(self, config, opsdroid=None):  # noqa: D107
             "store_path", str(Path(const.DEFAULT_ROOT_PATH, "matrix"))
         )
         self._ignore_unverified = True
-        self._allow_encryption = nio.crypto.ENCRYPTION_ENABLED
+        self._allow_encryption = config.get("enable_encryption", False)
+        if (
+            self._allow_encryption and not nio.crypto.ENCRYPTION_ENABLED
+        ):  # pragma: no cover
+            _LOGGER.warning(
+                "enable_encryption is True but encryption support is not available."
+            )
+            self._allow_encryption = False
 
         self._event_creator = MatrixEventCreator(self)
 
@@ -278,9 +287,10 @@ async def _parse_sync_response(self, response):
                         if event.source["type"] == "m.room.member":
                             event.source["content"] = event.content
                         if isinstance(event, nio.MegolmEvent):
-                            _LOGGER.error(
-                                f"Failed to decrypt event {event}"
-                            )  # pragma: nocover
+                            try:  # pragma: no cover
+                                event = self.connection.decrypt_event(event)
+                            except nio.exceptions.EncryptionError:  # pragma: no cover
+                                _LOGGER.exception(f"Failed to decrypt event {event}")
                         return await self._event_creator.create_event(
                             event.source, roomid
                         )


Test patch:
diff --git a/tests/test_connector_matrix.py b/tests/test_connector_matrix.py
--- a/tests/test_connector_matrix.py
+++ b/tests/test_connector_matrix.py
@@ -28,6 +28,7 @@ def connector():
             "mxid": "@opsdroid:localhost",
             "password": "hello",
             "homeserver": "http://localhost:8008",
+            "enable_encryption": True,
         }
     )
     api = nio.AsyncClient("https://notaurl.com", None)
diff --git a/tests/test_database_matrix.py b/tests/test_database_matrix.py
--- a/tests/test_database_matrix.py
+++ b/tests/test_database_matrix.py
@@ -29,6 +29,7 @@ def opsdroid_matrix(mocker):
             "mxid": "@opsdroid:localhost",
             "password": "hello",
             "homeserver": "http://localhost:8008",
+            "enable_encryption": True,
         }
     )
     connector.room_ids = {"main": "!notaroomid"}