Change to using switch on err types with nonexistent rooms

This commit is contained in:
Devon Hudson 2023-05-12 11:35:37 -06:00
parent a77f7e385a
commit 822618e8f7
No known key found for this signature in database
GPG key ID: CD06B18E77F6A628
15 changed files with 111 additions and 58 deletions

View file

@ -31,7 +31,7 @@ func AdminEvacuateRoom(req *http.Request, rsAPI roomserverAPI.ClientRoomserverAP
}
affected, err := rsAPI.PerformAdminEvacuateRoom(req.Context(), vars["roomID"])
switch err {
switch err.(type) {
case nil:
case eventutil.ErrRoomNoExists:
return util.JSONResponse{
@ -231,10 +231,10 @@ func AdminDownloadState(req *http.Request, device *api.Device, rsAPI roomserverA
}
}
if err = rsAPI.PerformAdminDownloadState(req.Context(), roomID, device.UserID, spec.ServerName(serverName)); err != nil {
if errors.Is(err, eventutil.ErrRoomNoExists) {
if errors.Is(err, eventutil.ErrRoomNoExists{}) {
return util.JSONResponse{
Code: 200,
JSON: spec.NotFound(eventutil.ErrRoomNoExists.Error()),
JSON: spec.NotFound(err.Error()),
}
}
logrus.WithError(err).WithFields(logrus.Fields{

View file

@ -16,7 +16,6 @@ package routing
import (
"encoding/json"
"errors"
"net/http"
"time"
@ -114,17 +113,16 @@ func JoinRoomByIDOrAlias(
Code: e.Code,
JSON: json.RawMessage(e.Message),
}
case eventutil.ErrRoomNoExists:
response = util.JSONResponse{
Code: http.StatusNotFound,
JSON: spec.NotFound(e.Error()),
}
default:
response = util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError(),
}
if errors.Is(err, eventutil.ErrRoomNoExists) {
response = util.JSONResponse{
Code: http.StatusNotFound,
JSON: spec.NotFound(e.Error()),
}
}
}
done <- response
}()

View file

@ -398,28 +398,33 @@ func checkAndProcessThreepid(
req.Context(), device, body, cfg, rsAPI, profileAPI,
roomID, evTime,
)
if err == threepid.ErrMissingParameter {
switch e := err.(type) {
case nil:
case threepid.ErrMissingParameter:
util.GetLogger(req.Context()).WithError(err).Error("threepid.CheckAndProcessInvite failed")
return inviteStored, &util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.BadJSON(err.Error()),
}
} else if err == threepid.ErrNotTrusted {
case threepid.ErrNotTrusted:
util.GetLogger(req.Context()).WithError(err).Error("threepid.CheckAndProcessInvite failed")
return inviteStored, &util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.NotTrusted(body.IDServer),
}
} else if err == eventutil.ErrRoomNoExists {
case eventutil.ErrRoomNoExists:
util.GetLogger(req.Context()).WithError(err).Error("threepid.CheckAndProcessInvite failed")
return inviteStored, &util.JSONResponse{
Code: http.StatusNotFound,
JSON: spec.NotFound(err.Error()),
}
} else if e, ok := err.(gomatrixserverlib.BadJSONError); ok {
case gomatrixserverlib.BadJSONError:
util.GetLogger(req.Context()).WithError(err).Error("threepid.CheckAndProcessInvite failed")
return inviteStored, &util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.BadJSON(e.Error()),
}
}
if err != nil {
default:
util.GetLogger(req.Context()).WithError(err).Error("threepid.CheckAndProcessInvite failed")
er := spec.InternalServerError()
return inviteStored, &er

View file

@ -16,6 +16,7 @@ package routing
import (
"context"
"errors"
"net/http"
"time"
@ -131,7 +132,7 @@ func SendRedaction(
var queryRes roomserverAPI.QueryLatestEventsAndStateResponse
e, err := eventutil.QueryAndBuildEvent(req.Context(), &proto, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
if err == eventutil.ErrRoomNoExists {
if errors.Is(err, eventutil.ErrRoomNoExists{}) {
return util.JSONResponse{
Code: http.StatusNotFound,
JSON: spec.NotFound("Room does not exist"),

View file

@ -284,28 +284,30 @@ func generateSendEvent(
var queryRes api.QueryLatestEventsAndStateResponse
e, err := eventutil.QueryAndBuildEvent(ctx, &proto, cfg.Matrix, identity, evTime, rsAPI, &queryRes)
if err == eventutil.ErrRoomNoExists {
switch specificErr := err.(type) {
case nil:
case eventutil.ErrRoomNoExists:
return nil, &util.JSONResponse{
Code: http.StatusNotFound,
JSON: spec.NotFound("Room does not exist"),
}
} else if e, ok := err.(gomatrixserverlib.BadJSONError); ok {
case gomatrixserverlib.BadJSONError:
return nil, &util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.BadJSON(e.Error()),
JSON: spec.BadJSON(specificErr.Error()),
}
} else if e, ok := err.(gomatrixserverlib.EventValidationError); ok {
if e.Code == gomatrixserverlib.EventValidationTooLarge {
case gomatrixserverlib.EventValidationError:
if specificErr.Code == gomatrixserverlib.EventValidationTooLarge {
return nil, &util.JSONResponse{
Code: http.StatusRequestEntityTooLarge,
JSON: spec.BadJSON(e.Error()),
JSON: spec.BadJSON(specificErr.Error()),
}
}
return nil, &util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.BadJSON(e.Error()),
JSON: spec.BadJSON(specificErr.Error()),
}
} else if err != nil {
default:
util.GetLogger(ctx).WithError(err).Error("eventutil.BuildEvent failed")
resErr := spec.InternalServerError()
return nil, &resErr

View file

@ -74,12 +74,15 @@ func RequestEmailToken(req *http.Request, threePIDAPI api.ClientUserAPI, cfg *co
}
resp.SID, err = threepid.CreateSession(req.Context(), body, cfg, client)
if err == threepid.ErrNotTrusted {
switch err.(type) {
case nil:
case threepid.ErrNotTrusted:
util.GetLogger(req.Context()).WithError(err).Error("threepid.CreateSession failed")
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.NotTrusted(body.IDServer),
}
} else if err != nil {
default:
util.GetLogger(req.Context()).WithError(err).Error("threepid.CreateSession failed")
return spec.InternalServerError()
}
@ -102,12 +105,15 @@ func CheckAndSave3PIDAssociation(
// Check if the association has been validated
verified, address, medium, err := threepid.CheckAssociation(req.Context(), body.Creds, cfg, client)
if err == threepid.ErrNotTrusted {
switch err.(type) {
case nil:
case threepid.ErrNotTrusted:
util.GetLogger(req.Context()).WithError(err).Error("threepid.CheckAssociation failed")
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.NotTrusted(body.Creds.IDServer),
}
} else if err != nil {
default:
util.GetLogger(req.Context()).WithError(err).Error("threepid.CheckAssociation failed")
return spec.InternalServerError()
}

View file

@ -68,7 +68,7 @@ func UpgradeRoom(
JSON: spec.Forbidden(e.Error()),
}
default:
if errors.Is(err, eventutil.ErrRoomNoExists) {
if errors.Is(err, eventutil.ErrRoomNoExists{}) {
return util.JSONResponse{
Code: http.StatusNotFound,
JSON: spec.NotFound("Room does not exist"),

View file

@ -64,14 +64,34 @@ type idServerStoreInviteResponse struct {
}
var (
// ErrMissingParameter is the error raised if a request for 3PID invite has
// an incomplete body
ErrMissingParameter = errors.New("'address', 'id_server' and 'medium' must all be supplied")
// ErrNotTrusted is the error raised if an identity server isn't in the list
// of trusted servers in the configuration file.
ErrNotTrusted = errors.New("untrusted server")
errMissingParameter = fmt.Errorf("'address', 'id_server' and 'medium' must all be supplied")
errNotTrusted = fmt.Errorf("untrusted server")
)
// ErrMissingParameter is the error raised if a request for 3PID invite has
// an incomplete body
type ErrMissingParameter struct{}
func (e ErrMissingParameter) Error() string {
return errMissingParameter.Error()
}
func (e ErrMissingParameter) Unwrap() error {
return errMissingParameter
}
// ErrNotTrusted is the error raised if an identity server isn't in the list
// of trusted servers in the configuration file.
type ErrNotTrusted struct{}
func (e ErrNotTrusted) Error() string {
return errNotTrusted.Error()
}
func (e ErrNotTrusted) Unwrap() error {
return errNotTrusted
}
// CheckAndProcessInvite analyses the body of an incoming membership request.
// If the fields relative to a third-party-invite are all supplied, lookups the
// matching Matrix ID from the given identity server. If no Matrix ID is
@ -99,7 +119,7 @@ func CheckAndProcessInvite(
} else if body.Address == "" || body.IDServer == "" || body.Medium == "" {
// If at least one of the 3PID-specific fields is supplied but not all
// of them, return an error
err = ErrMissingParameter
err = ErrMissingParameter{}
return
}

View file

@ -186,5 +186,5 @@ func isTrusted(idServer string, cfg *config.ClientAPI) error {
return nil
}
}
return ErrNotTrusted
return ErrNotTrusted{}
}

View file

@ -119,20 +119,24 @@ func MakeJoin(
RoomVersion: roomVersion,
}
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), proto, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
if err == eventutil.ErrRoomNoExists {
switch e := err.(type) {
case nil:
case eventutil.ErrRoomNoExists:
util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
return nil, nil, &util.JSONResponse{
Code: http.StatusNotFound,
JSON: spec.NotFound("Room does not exist"),
}
} else if e, ok := err.(gomatrixserverlib.BadJSONError); ok {
case gomatrixserverlib.BadJSONError:
util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
return nil, nil, &util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.BadJSON(e.Error()),
}
} else if err != nil {
default:
util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
e := spec.InternalServerError()
return nil, nil, &e
internalErr := spec.InternalServerError()
return nil, nil, &internalErr
}
stateEvents := make([]gomatrixserverlib.PDU, len(queryRes.StateEvents))

View file

@ -75,17 +75,21 @@ func MakeLeave(
var queryRes api.QueryLatestEventsAndStateResponse
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), &proto, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
if err == eventutil.ErrRoomNoExists {
switch e := err.(type) {
case nil:
case eventutil.ErrRoomNoExists:
util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
return util.JSONResponse{
Code: http.StatusNotFound,
JSON: spec.NotFound("Room does not exist"),
}
} else if e, ok := err.(gomatrixserverlib.BadJSONError); ok {
case gomatrixserverlib.BadJSONError:
util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.BadJSON(e.Error()),
}
} else if err != nil {
default:
util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
return spec.InternalServerError()
}

View file

@ -31,7 +31,17 @@ import (
// ErrRoomNoExists is returned when trying to lookup the state of a room that
// doesn't exist
var ErrRoomNoExists = errors.New("room does not exist")
var errRoomNoExists = fmt.Errorf("room does not exist")
type ErrRoomNoExists struct{}
func (e ErrRoomNoExists) Error() string {
return errRoomNoExists.Error()
}
func (e ErrRoomNoExists) Unwrap() error {
return errRoomNoExists
}
// QueryAndBuildEvent builds a Matrix event using the event builder and roomserver query
// API client provided. If also fills roomserver query API response (if provided)
@ -116,7 +126,7 @@ func addPrevEventsToEvent(
queryRes *api.QueryLatestEventsAndStateResponse,
) error {
if !queryRes.RoomExists {
return ErrRoomNoExists
return ErrRoomNoExists{}
}
verImpl, err := gomatrixserverlib.GetRoomVersion(queryRes.RoomVersion)

View file

@ -52,7 +52,7 @@ func (r *Admin) PerformAdminEvacuateRoom(
return nil, err
}
if roomInfo == nil || roomInfo.IsStub() {
return nil, eventutil.ErrRoomNoExists
return nil, eventutil.ErrRoomNoExists{}
}
memberNIDs, err := r.DB.GetMembershipEventNIDsForRoom(ctx, roomInfo.RoomNID, true, true)
@ -240,7 +240,7 @@ func (r *Admin) PerformAdminDownloadState(
}
if roomInfo == nil || roomInfo.IsStub() {
return eventutil.ErrRoomNoExists
return eventutil.ErrRoomNoExists{}
}
fwdExtremities, _, depth, err := r.DB.LatestEventIDs(ctx, roomInfo.RoomNID)

View file

@ -286,7 +286,7 @@ func (r *Joiner) performJoinRoomByID(
}
event, err := eventutil.QueryAndBuildEvent(ctx, &proto, r.Cfg.Matrix, identity, time.Now(), r.RSAPI, &buildRes)
switch err {
switch err.(type) {
case nil:
// The room join is local. Send the new join event into the
// roomserver. First of all check that the user isn't already
@ -328,7 +328,7 @@ func (r *Joiner) performJoinRoomByID(
// Otherwise we'll try a federated join as normal, since it's quite
// possible that the room still exists on other servers.
if len(req.ServerNames) == 0 {
return "", "", eventutil.ErrRoomNoExists
return "", "", eventutil.ErrRoomNoExists{}
}
}

View file

@ -274,7 +274,7 @@ func publishNewRoomAndUnpublishOldRoom(
func (r *Upgrader) validateRoomExists(ctx context.Context, roomID string) error {
if _, err := r.URSAPI.QueryRoomVersionForRoom(ctx, roomID); err != nil {
return eventutil.ErrRoomNoExists
return eventutil.ErrRoomNoExists{}
}
return nil
}
@ -556,15 +556,18 @@ func (r *Upgrader) makeHeaderedEvent(ctx context.Context, evTime time.Time, user
}
var queryRes api.QueryLatestEventsAndStateResponse
headeredEvent, err := eventutil.QueryAndBuildEvent(ctx, &proto, r.Cfg.Matrix, identity, evTime, r.URSAPI, &queryRes)
if err == eventutil.ErrRoomNoExists {
return nil, err
} else if e, ok := err.(gomatrixserverlib.BadJSONError); ok {
switch e := err.(type) {
case nil:
case eventutil.ErrRoomNoExists:
return nil, e
} else if e, ok := err.(gomatrixserverlib.EventValidationError); ok {
case gomatrixserverlib.BadJSONError:
return nil, e
} else if err != nil {
case gomatrixserverlib.EventValidationError:
return nil, e
default:
return nil, fmt.Errorf("failed to build new %q event: %w", proto.Type, err)
}
// check to see if this user can perform this operation
stateEvents := make([]gomatrixserverlib.PDU, len(queryRes.StateEvents))
for i := range queryRes.StateEvents {