From 9e3fa96fb42f287ace7369637ba4973883133df3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 12 Dec 2025 17:31:56 +0200 Subject: [PATCH] bridgev2/portal: handle portal deletion edge cases --- bridgev2/errors.go | 1 + bridgev2/portal.go | 6 ++++++ bridgev2/queue.go | 6 +++--- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/bridgev2/errors.go b/bridgev2/errors.go index c39f8707..514dc238 100644 --- a/bridgev2/errors.go +++ b/bridgev2/errors.go @@ -39,6 +39,7 @@ var ErrNotLoggedIn = errors.New("not logged in") var ErrDirectMediaNotEnabled = errors.New("direct media is not enabled") var ErrPortalIsDeleted = errors.New("portal is deleted") +var ErrPortalNotFoundInEventHandler = errors.New("portal not found to handle remote event") // Common message status errors var ( diff --git a/bridgev2/portal.go b/bridgev2/portal.go index 273b1fd3..7d479be2 100644 --- a/bridgev2/portal.go +++ b/bridgev2/portal.go @@ -5195,6 +5195,9 @@ func (portal *Portal) addToUserSpaces(ctx context.Context) { } func (portal *Portal) Delete(ctx context.Context) error { + if portal.deleted.IsSet() { + return nil + } portal.removeInPortalCache(ctx) err := portal.Bridge.DB.Portal.Delete(ctx, portal.PortalKey) if err != nil { @@ -5254,6 +5257,9 @@ func (portal *Portal) unlockedDelete(ctx context.Context) error { } func (portal *Portal) unlockedDeleteCache() { + if portal.deleted.IsSet() { + return + } delete(portal.Bridge.portalsByKey, portal.PortalKey) if portal.MXID != "" { delete(portal.Bridge.portalsByMXID, portal.MXID) diff --git a/bridgev2/queue.go b/bridgev2/queue.go index 6667caea..3775c825 100644 --- a/bridgev2/queue.go +++ b/bridgev2/queue.go @@ -220,7 +220,7 @@ func (ul *UserLogin) QueueRemoteEvent(evt RemoteEvent) EventHandlingResult { return ul.Bridge.QueueRemoteEvent(ul, evt) } -func (br *Bridge) QueueRemoteEvent(login *UserLogin, evt RemoteEvent) (res EventHandlingResult) { +func (br *Bridge) QueueRemoteEvent(login *UserLogin, evt RemoteEvent) EventHandlingResult { log := login.Log ctx := log.WithContext(br.BackgroundCtx) maybeUncertain, ok := evt.(RemoteEventWithUncertainPortalReceiver) @@ -236,14 +236,14 @@ func (br *Bridge) QueueRemoteEvent(login *UserLogin, evt RemoteEvent) (res Event if err != nil { log.Err(err).Object("portal_key", key).Bool("uncertain_receiver", isUncertain). Msg("Failed to get portal to handle remote event") - return + return EventHandlingResultFailed.WithError(fmt.Errorf("failed to get portal: %w", err)) } else if portal == nil { log.Warn(). Stringer("event_type", evt.GetType()). Object("portal_key", key). Bool("uncertain_receiver", isUncertain). Msg("Portal not found to handle remote event") - return + return EventHandlingResultFailed.WithError(ErrPortalNotFoundInEventHandler) } // TODO put this in a better place, and maybe cache to avoid constant db queries login.MarkInPortal(ctx, portal)