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.
This commit is contained in:
Neil Alexander 2022-02-21 16:22:29 +00:00 committed by GitHub
parent cf525d1f61
commit aa6bbf484a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 18 additions and 3 deletions

View file

@ -29,6 +29,7 @@ import (
"github.com/matrix-org/dendrite/roomserver/internal/input" "github.com/matrix-org/dendrite/roomserver/internal/input"
"github.com/matrix-org/dendrite/roomserver/internal/query" "github.com/matrix-org/dendrite/roomserver/internal/query"
"github.com/matrix-org/dendrite/roomserver/storage" "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/dendrite/setup/config"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -367,8 +368,16 @@ func buildEvent(
StateToFetch: eventsNeeded.Tuples(), StateToFetch: eventsNeeded.Tuples(),
}, &queryRes) }, &queryRes)
if err != nil { 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) return nil, nil, fmt.Errorf("QueryLatestEventsAndState: %w", err)
} }
}
ev, err := eventutil.BuildEvent(ctx, builder, cfg, time.Now(), &eventsNeeded, &queryRes) ev, err := eventutil.BuildEvent(ctx, builder, cfg, time.Now(), &eventsNeeded, &queryRes)
if err != nil { if err != nil {

View file

@ -134,7 +134,7 @@ func (s *stateSnapshotStatements) BulkSelectStateBlockNIDs(
return nil, err return nil, err
} }
if i != len(stateNIDs) { 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 return results, nil
} }

View file

@ -137,7 +137,7 @@ func (s *stateSnapshotStatements) BulkSelectStateBlockNIDs(
} }
} }
if i != len(stateNIDs) { 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 return results, nil
} }

View file

@ -213,6 +213,12 @@ type MissingEventError string
func (e MissingEventError) Error() string { return string(e) } 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 // A RejectedError is returned when an event is stored as rejected. The error
// contains the reason why. // contains the reason why.
type RejectedError string type RejectedError string