diff --git a/clientapi/routing/createroom.go b/clientapi/routing/createroom.go index 35ab2d5d7..36837d408 100644 --- a/clientapi/routing/createroom.go +++ b/clientapi/routing/createroom.go @@ -402,15 +402,23 @@ func createRoom( } } // Send the invite event to the roomserver. - if err := roomserverAPI.SendInvite( + err = roomserverAPI.SendInvite( req.Context(), rsAPI, inviteEvent.Headered(roomVersion), strippedState, // invite room state cfg.Matrix.ServerName, // send as server nil, // transaction ID - ); err != nil { - util.GetLogger(req.Context()).WithError(err).Error("SendInvite failed") - return jsonerror.InternalServerError() + ) + switch e := err.(type) { + case *roomserverAPI.PerformError: + return e.JSONResponse() + case nil: + default: + util.GetLogger(req.Context()).WithError(err).Error("roomserverAPI.SendInvite failed") + return util.JSONResponse{ + Code: http.StatusInternalServerError, + JSON: jsonerror.InternalServerError(), + } } } diff --git a/clientapi/routing/membership.go b/clientapi/routing/membership.go index cda728dc3..37fafa5ad 100644 --- a/clientapi/routing/membership.go +++ b/clientapi/routing/membership.go @@ -221,17 +221,21 @@ func SendInvite( cfg.Matrix.ServerName, nil, ) - if err != nil { + switch e := err.(type) { + case *roomserverAPI.PerformError: + return e.JSONResponse() + case nil: + return util.JSONResponse{ + Code: http.StatusOK, + JSON: struct{}{}, + } + default: util.GetLogger(req.Context()).WithError(err).Error("roomserverAPI.SendInvite failed") return util.JSONResponse{ - Code: http.StatusForbidden, - JSON: jsonerror.Forbidden(err.Error()), + Code: http.StatusInternalServerError, + JSON: jsonerror.InternalServerError(), } } - return util.JSONResponse{ - Code: http.StatusOK, - JSON: struct{}{}, - } } func buildMembershipEvent( diff --git a/federationapi/routing/invite.go b/federationapi/routing/invite.go index eb65de641..0453af40e 100644 --- a/federationapi/routing/invite.go +++ b/federationapi/routing/invite.go @@ -143,17 +143,24 @@ func processInvite( ) // Add the invite event to the roomserver. - if err := api.SendInvite( + err = api.SendInvite( ctx, rsAPI, signedEvent.Headered(roomVer), strippedState, api.DoNotSendToOtherServers, nil, - ); err != nil { - util.GetLogger(ctx).WithError(err).Error("producer.SendInvite failed") - return jsonerror.InternalServerError() - } - - // Return the signed event to the originating server, it should then tell - // the other servers in the room that we have been invited. - return util.JSONResponse{ - Code: http.StatusOK, - JSON: gomatrixserverlib.RespInviteV2{Event: signedEvent}, + ) + switch e := err.(type) { + case *api.PerformError: + return e.JSONResponse() + case nil: + // Return the signed event to the originating server, it should then tell + // the other servers in the room that we have been invited. + return util.JSONResponse{ + Code: http.StatusOK, + JSON: gomatrixserverlib.RespInviteV2{Event: signedEvent}, + } + default: + util.GetLogger(ctx).WithError(err).Error("api.SendInvite failed") + return util.JSONResponse{ + Code: http.StatusInternalServerError, + JSON: jsonerror.InternalServerError(), + } } } diff --git a/roomserver/api/perform.go b/roomserver/api/perform.go index e3ce7da4a..d7f72a997 100644 --- a/roomserver/api/perform.go +++ b/roomserver/api/perform.go @@ -105,6 +105,7 @@ type PerformInviteRequest struct { } type PerformInviteResponse struct { + Error *PerformError `json:"error"` } // PerformBackfillRequest is a request to PerformBackfill. diff --git a/roomserver/api/wrapper.go b/roomserver/api/wrapper.go index 00640d382..d110bfc5d 100644 --- a/roomserver/api/wrapper.go +++ b/roomserver/api/wrapper.go @@ -112,6 +112,9 @@ func SendInvite( } response := &PerformInviteResponse{} if err := rsAPI.PerformInvite(ctx, request, response); err != nil { + if response.Error != nil { + return response.Error + } return fmt.Errorf("rsAPI.PerformInvite: %w", err) } diff --git a/roomserver/internal/perform_invite.go b/roomserver/internal/perform_invite.go index feef584d8..75a1d49a6 100644 --- a/roomserver/internal/perform_invite.go +++ b/roomserver/internal/perform_invite.go @@ -2,7 +2,6 @@ package internal import ( "context" - "errors" "fmt" federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api" @@ -48,17 +47,17 @@ func (r *RoomserverInternalAPI) PerformInvite( } if len(inviteState) == 0 { if err := event.SetUnsignedField("invite_room_state", struct{}{}); err != nil { - return err + return fmt.Errorf("event.SetUnsignedField: %w", err) } } else { if err := event.SetUnsignedField("invite_room_state", inviteState); err != nil { - return err + return fmt.Errorf("event.SetUnsignedField: %w", err) } } updater, err := r.DB.MembershipUpdater(ctx, roomID, targetUserID, isTargetLocal, req.RoomVersion) if err != nil { - return err + return fmt.Errorf("r.DB.MembershipUpdater: %w", err) } succeeded := false defer func() { @@ -96,7 +95,11 @@ func (r *RoomserverInternalAPI) PerformInvite( // For now we will implement option 2. Since in the abesence of a retry // mechanism it will be equivalent to option 1, and we don't have a // signalling mechanism to implement option 3. - return errors.New("The user is already in the room") + res.Error = &api.PerformError{ + Code: api.PerformErrorNoOperation, + Msg: "User is already joined to room", + } + return res.Error } if isOriginLocal { @@ -108,10 +111,11 @@ func (r *RoomserverInternalAPI) PerformInvite( "processInviteEvent.checkAuthEvents failed for event", ) if _, ok := err.(*gomatrixserverlib.NotAllowed); ok { - return &api.PerformError{ + res.Error = &api.PerformError{ Msg: err.Error(), Code: api.PerformErrorNotAllowed, } + return fmt.Errorf("checkAuthEvents: %w", err) } return err } @@ -128,6 +132,10 @@ func (r *RoomserverInternalAPI) PerformInvite( } fsRes := &federationSenderAPI.PerformInviteResponse{} if err = r.fsAPI.PerformInvite(ctx, fsReq, fsRes); err != nil { + res.Error = &api.PerformError{ + Msg: err.Error(), + Code: api.PerformErrorNoOperation, + } return fmt.Errorf("r.fsAPI.PerformInvite: %w", err) } event = fsRes.SignedEvent @@ -137,11 +145,11 @@ func (r *RoomserverInternalAPI) PerformInvite( unwrapped := event.Unwrap() outputUpdates, err := updateToInviteMembership(updater, &unwrapped, nil, req.Event.RoomVersion) if err != nil { - return err + return fmt.Errorf("updateToInviteMembership: %w", err) } if err = r.WriteOutputEvents(roomID, outputUpdates); err != nil { - return err + return fmt.Errorf("r.WriteOutputEvents: %w", err) } succeeded = true