forked from MirrorHub/synapse
Fix error handling for rooms whose versions are unknown. (#5219)
If we remove support for a particular room version, we should behave more gracefully. This should make client requests fail with a 400 rather than a 500, and will ignore individiual PDUs in a federation transaction, rather than the whole transaction.
This commit is contained in:
parent
24b93b9c76
commit
04d53794d6
5 changed files with 39 additions and 8 deletions
1
changelog.d/5219.bugfix
Normal file
1
changelog.d/5219.bugfix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Fix error handling for rooms whose versions are unknown.
|
|
@ -328,9 +328,23 @@ class RoomKeysVersionError(SynapseError):
|
||||||
self.current_version = current_version
|
self.current_version = current_version
|
||||||
|
|
||||||
|
|
||||||
class IncompatibleRoomVersionError(SynapseError):
|
class UnsupportedRoomVersionError(SynapseError):
|
||||||
"""A server is trying to join a room whose version it does not support."""
|
"""The client's request to create a room used a room version that the server does
|
||||||
|
not support."""
|
||||||
|
def __init__(self):
|
||||||
|
super(UnsupportedRoomVersionError, self).__init__(
|
||||||
|
code=400,
|
||||||
|
msg="Homeserver does not support this room version",
|
||||||
|
errcode=Codes.UNSUPPORTED_ROOM_VERSION,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class IncompatibleRoomVersionError(SynapseError):
|
||||||
|
"""A server is trying to join a room whose version it does not support.
|
||||||
|
|
||||||
|
Unlike UnsupportedRoomVersionError, it is specific to the case of the make_join
|
||||||
|
failing.
|
||||||
|
"""
|
||||||
def __init__(self, room_version):
|
def __init__(self, room_version):
|
||||||
super(IncompatibleRoomVersionError, self).__init__(
|
super(IncompatibleRoomVersionError, self).__init__(
|
||||||
code=400,
|
code=400,
|
||||||
|
|
|
@ -21,6 +21,7 @@ import six
|
||||||
|
|
||||||
from unpaddedbase64 import encode_base64
|
from unpaddedbase64 import encode_base64
|
||||||
|
|
||||||
|
from synapse.api.errors import UnsupportedRoomVersionError
|
||||||
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS, EventFormatVersions
|
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS, EventFormatVersions
|
||||||
from synapse.util.caches import intern_dict
|
from synapse.util.caches import intern_dict
|
||||||
from synapse.util.frozenutils import freeze
|
from synapse.util.frozenutils import freeze
|
||||||
|
@ -369,12 +370,15 @@ def room_version_to_event_format(room_version):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
int
|
int
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
UnsupportedRoomVersionError if the room version is unknown
|
||||||
"""
|
"""
|
||||||
v = KNOWN_ROOM_VERSIONS.get(room_version)
|
v = KNOWN_ROOM_VERSIONS.get(room_version)
|
||||||
|
|
||||||
if not v:
|
if not v:
|
||||||
# We should have already checked version, so this should not happen
|
# this can happen if support is withdrawn for a room version
|
||||||
raise RuntimeError("Unrecognized room version %s" % (room_version,))
|
raise UnsupportedRoomVersionError()
|
||||||
|
|
||||||
return v.event_format
|
return v.event_format
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import attr
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from synapse.api.constants import MAX_DEPTH
|
from synapse.api.constants import MAX_DEPTH
|
||||||
|
from synapse.api.errors import UnsupportedRoomVersionError
|
||||||
from synapse.api.room_versions import (
|
from synapse.api.room_versions import (
|
||||||
KNOWN_EVENT_FORMAT_VERSIONS,
|
KNOWN_EVENT_FORMAT_VERSIONS,
|
||||||
KNOWN_ROOM_VERSIONS,
|
KNOWN_ROOM_VERSIONS,
|
||||||
|
@ -178,9 +179,8 @@ class EventBuilderFactory(object):
|
||||||
"""
|
"""
|
||||||
v = KNOWN_ROOM_VERSIONS.get(room_version)
|
v = KNOWN_ROOM_VERSIONS.get(room_version)
|
||||||
if not v:
|
if not v:
|
||||||
raise Exception(
|
# this can happen if support is withdrawn for a room version
|
||||||
"No event format defined for version %r" % (room_version,)
|
raise UnsupportedRoomVersionError()
|
||||||
)
|
|
||||||
return self.for_room_version(v, key_values)
|
return self.for_room_version(v, key_values)
|
||||||
|
|
||||||
def for_room_version(self, room_version, key_values):
|
def for_room_version(self, room_version, key_values):
|
||||||
|
|
|
@ -33,6 +33,7 @@ from synapse.api.errors import (
|
||||||
IncompatibleRoomVersionError,
|
IncompatibleRoomVersionError,
|
||||||
NotFoundError,
|
NotFoundError,
|
||||||
SynapseError,
|
SynapseError,
|
||||||
|
UnsupportedRoomVersionError,
|
||||||
)
|
)
|
||||||
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS
|
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS
|
||||||
from synapse.crypto.event_signing import compute_event_signature
|
from synapse.crypto.event_signing import compute_event_signature
|
||||||
|
@ -198,11 +199,22 @@ class FederationServer(FederationBase):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
room_version = yield self.store.get_room_version(room_id)
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
format_ver = room_version_to_event_format(room_version)
|
|
||||||
except NotFoundError:
|
except NotFoundError:
|
||||||
logger.info("Ignoring PDU for unknown room_id: %s", room_id)
|
logger.info("Ignoring PDU for unknown room_id: %s", room_id)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
format_ver = room_version_to_event_format(room_version)
|
||||||
|
except UnsupportedRoomVersionError:
|
||||||
|
# this can happen if support for a given room version is withdrawn,
|
||||||
|
# so that we still get events for said room.
|
||||||
|
logger.info(
|
||||||
|
"Ignoring PDU for room %s with unknown version %s",
|
||||||
|
room_id,
|
||||||
|
room_version,
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
event = event_from_pdu_json(p, format_ver)
|
event = event_from_pdu_json(p, format_ver)
|
||||||
pdus_by_room.setdefault(room_id, []).append(event)
|
pdus_by_room.setdefault(room_id, []).append(event)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue