Return `ErrRoomNoExists` if insufficient state is available for a `buildEvent` to succeed when joining a room
This may help cases like since it should prompt us to try a federated join again instead.
MODIFY
roomserver/internal/perform/perform_join.go
roomserver/internal/perform/perform_join.go
@@ -29,6 +29,7 @@ import (
"github.com/matrix-org/dendrite/roomserver/internal/input"
"github.com/matrix-org/dendrite/roomserver/internal/query"
"github.com/matrix-org/dendrite/roomserver/storage"
+ "github.com/matrix-org/dendrite/roomserver/types"
"github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/gomatrixserverlib"
"github.com/sirupsen/logrus"
@@ -367,8 +368,16 @@ func buildEvent(
StateToFetch: eventsNeeded.Tuples(),
}, &queryRes)
if err != nil {
+ switch err.(type) {
+ case types.MissingStateError:
+ // We know something about the room but the state seems to be
+ // insufficient to actually build a new event, so in effect we
+ // had might as well treat the room as if it doesn't exist.
+ return nil, nil, eventutil.ErrRoomNoExists
+ default:
return nil, nil, fmt.Errorf("QueryLatestEventsAndState: %w", err)
}
+ }
ev, err := eventutil.BuildEvent(ctx, builder, cfg, time.Now(), &eventsNeeded, &queryRes)
if err != nil {

MODIFY
roomserver/storage/postgres/state_snapshot_table.go
roomserver/storage/postgres/state_snapshot_table.go
@@ -134,7 +134,7 @@ func (s *stateSnapshotStatements) BulkSelectStateBlockNIDs(
return nil, err
}
if i != len(stateNIDs) {
- return nil, fmt.Errorf("storage: state NIDs missing from the database (%d != %d)", i, len(stateNIDs))
+ return nil, types.MissingStateError(fmt.Sprintf("storage: state NIDs missing from the database (%d != %d)", i, len(stateNIDs)))
}
return results, nil
}

MODIFY
roomserver/storage/sqlite3/state_snapshot_table.go
roomserver/storage/sqlite3/state_snapshot_table.go
@@ -137,7 +137,7 @@ func (s *stateSnapshotStatements) BulkSelectStateBlockNIDs(
}
}
if i != len(stateNIDs) {
- return nil, fmt.Errorf("storage: state NIDs missing from the database (%d != %d)", i, len(stateNIDs))
+ return nil, types.MissingStateError(fmt.Sprintf("storage: state NIDs missing from the database (%d != %d)", i, len(stateNIDs)))
}
return results, nil
}

MODIFY
roomserver/types/types.go
roomserver/types/types.go
@@ -213,6 +213,12 @@ type MissingEventError string
func (e MissingEventError) Error() string { return string(e) }
+// A MissingStateError is an error that happened because the roomserver was
+// missing requested state snapshots from its databases.
+type MissingStateError string
+
+func (e MissingStateError) Error() string { return string(e) }
+
// A RejectedError is returned when an event is stored as rejected. The error
// contains the reason why.
type RejectedError string

Return `ErrRoomNoExists` if insufficient state is available for a `buildEvent` to succeed when joining a room (#2210)

This may help cases like #2206, since it should prompt us to try a federated join again instead.