bugfix: ensure newly joined live-stream rooms don't cause 500s

This was caused by the GlobalCache not having a metadata entry for
the new room, which in some cases prevented a stub from being made.

With regression test.
This commit is contained in:
Kegan Dougal 2022-08-10 19:48:03 +01:00
parent 47ddc04652
commit 54e1cfbb0e
5 changed files with 58 additions and 1 deletions

View File

@ -372,7 +372,7 @@ func (c *UserCache) newRoomUpdate(roomID string) RoomUpdate {
u := c.LoadRoomData(roomID)
var r *internal.RoomMetadata
globalRooms := c.globalCache.LoadRooms(roomID)
if globalRooms == nil {
if globalRooms == nil || globalRooms[roomID] == nil {
// this can happen when we join a room we didn't know about because we process unread counts
// before the timeline events. Warn and send a stub
logger.Warn().Str("room", roomID).Msg("UserCache update: room doesn't exist in global cache yet, generating stub")
@ -382,6 +382,7 @@ func (c *UserCache) newRoomUpdate(roomID string) RoomUpdate {
} else {
r = globalRooms[roomID]
}
internal.Assert("missing global room metadata for room "+roomID, r != nil)
return &roomUpdateCache{
roomID: roomID,
globalRoomData: r,

View File

@ -401,8 +401,10 @@ func (s *ConnState) OnRoomUpdate(up caches.RoomUpdate) {
return
}
}
internal.Assert("missing global room metadata", update.GlobalRoomMetadata() != nil)
s.live.onUpdate(update)
case caches.RoomUpdate:
internal.Assert("missing global room metadata", update.GlobalRoomMetadata() != nil)
s.live.onUpdate(update)
default:
logger.Warn().Str("room_id", up.RoomID()).Msg("OnRoomUpdate unknown update type")

View File

@ -206,6 +206,7 @@ func (f *FilteredSortableRooms) Add(r RoomConnMetadata) bool {
}
func (f *FilteredSortableRooms) UpdateGlobalRoomMetadata(r *internal.RoomMetadata) int {
internal.Assert("missing room metadata", r != nil)
index, ok := f.SortableRooms.IndexOf(r.RoomID)
if !ok {
return -1

View File

@ -502,3 +502,49 @@ func TestMultipleOverlappingLists(t *testing.T) {
}),
)
}
// Regression test for a panic when new rooms were live-streamed to the client in Element-Web
func TestNot500OnNewRooms(t *testing.T) {
boolTrue := true
boolFalse := false
mSpace := "m.space"
alice := registerNewUser(t)
res := alice.SlidingSync(t, sync3.Request{
Lists: []sync3.RequestList{
{
SlowGetAllRooms: &boolTrue,
Filters: &sync3.RequestFilters{
RoomTypes: []*string{&mSpace},
},
},
},
})
alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat"})
alice.SlidingSync(t, sync3.Request{
Lists: []sync3.RequestList{
{
SlowGetAllRooms: &boolTrue,
Filters: &sync3.RequestFilters{
RoomTypes: []*string{&mSpace},
},
},
{
Filters: &sync3.RequestFilters{
IsDM: &boolFalse,
},
Ranges: sync3.SliceRanges{{0, 20}},
},
},
}, WithPos(res.Pos))
alice.CreateRoom(t, map[string]interface{}{"preset": "public_chat"})
alice.SlidingSync(t, sync3.Request{
Lists: []sync3.RequestList{
{
SlowGetAllRooms: &boolTrue,
},
{
Ranges: sync3.SliceRanges{{0, 20}},
},
},
}, WithPos(res.Pos))
}

View File

@ -63,6 +63,13 @@ func NewJoinEvent(t TestBenchInterface, userID string, modifiers ...eventMockMod
}, modifiers...)
}
func NewMessageEvent(t TestBenchInterface, userID, text string) json.RawMessage {
return NewEvent(t, "m.room.message", userID, map[string]interface{}{
"msgtype": "m.text",
"body": text,
})
}
func NewStateEvent(t TestBenchInterface, evType, stateKey, sender string, content interface{}, modifiers ...eventMockModifier) json.RawMessage {
t.Helper()
e := &eventMock{