diff options
author | Kegsay <kegan@matrix.org> | 2020-06-25 15:04:48 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-25 15:04:48 +0100 |
commit | 43cddfe00f53e3a2df4769be31c66cd818a2966e (patch) | |
tree | d7947effce9b38e94f04fce7adda71d0195c021f /federationsender | |
parent | c2d34422d65e81eee6e9d0c31a4c5a446fa9678a (diff) |
Return remote errors from FS.PerformJoin (#1164)
* Return remote errors from FS.PerformJoin
Follows the same pattern as PerformJoin on roomserver (no error return).
Also return the right format for incompatible room version errors.
Makes a bunch of tests pass!
* Handle network errors better when returning remote HTTP errors
* Linting
* Fix tests
* Update whitelist, pass network errors through in API=1 mode
Diffstat (limited to 'federationsender')
-rw-r--r-- | federationsender/api/api.go | 4 | ||||
-rw-r--r-- | federationsender/internal/perform.go | 28 | ||||
-rw-r--r-- | federationsender/inthttp/client.go | 12 | ||||
-rw-r--r-- | federationsender/inthttp/server.go | 4 |
4 files changed, 37 insertions, 11 deletions
diff --git a/federationsender/api/api.go b/federationsender/api/api.go index 02c76258..d90ffd29 100644 --- a/federationsender/api/api.go +++ b/federationsender/api/api.go @@ -4,6 +4,7 @@ import ( "context" "github.com/matrix-org/dendrite/federationsender/types" + "github.com/matrix-org/gomatrix" "github.com/matrix-org/gomatrixserverlib" ) @@ -28,7 +29,7 @@ type FederationSenderInternalAPI interface { ctx context.Context, request *PerformJoinRequest, response *PerformJoinResponse, - ) error + ) // Handle an instruction to make_leave & send_leave with a remote server. PerformLeave( ctx context.Context, @@ -62,6 +63,7 @@ type PerformJoinRequest struct { } type PerformJoinResponse struct { + LastError *gomatrix.HTTPError } type PerformLeaveRequest struct { diff --git a/federationsender/internal/perform.go b/federationsender/internal/perform.go index 7ced4af8..96b1149d 100644 --- a/federationsender/internal/perform.go +++ b/federationsender/internal/perform.go @@ -2,6 +2,7 @@ package internal import ( "context" + "errors" "fmt" "time" @@ -9,6 +10,7 @@ import ( "github.com/matrix-org/dendrite/federationsender/internal/perform" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/roomserver/version" + "github.com/matrix-org/gomatrix" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" "github.com/sirupsen/logrus" @@ -40,7 +42,7 @@ func (r *FederationSenderInternalAPI) PerformJoin( ctx context.Context, request *api.PerformJoinRequest, response *api.PerformJoinResponse, -) (err error) { +) { // Look up the supported room versions. var supportedVersions []gomatrixserverlib.RoomVersion for version := range version.SupportedRoomVersions() { @@ -63,6 +65,7 @@ func (r *FederationSenderInternalAPI) PerformJoin( // Try each server that we were provided until we land on one that // successfully completes the make-join send-join dance. + var lastErr error for _, serverName := range request.ServerNames { if err := r.performJoinUsingServer( ctx, @@ -76,17 +79,32 @@ func (r *FederationSenderInternalAPI) PerformJoin( "server_name": serverName, "room_id": request.RoomID, }).Warnf("Failed to join room through server") + lastErr = err continue } // We're all good. - return nil + return } // If we reach here then we didn't complete a join for some reason. - return fmt.Errorf( - "failed to join user %q to room %q through %d server(s)", - request.UserID, request.RoomID, len(request.ServerNames), + var httpErr gomatrix.HTTPError + if ok := errors.As(lastErr, &httpErr); ok { + httpErr.Message = string(httpErr.Contents) + // Clear the wrapped error, else serialising to JSON (in polylith mode) will fail + httpErr.WrappedError = nil + response.LastError = &httpErr + } else { + response.LastError = &gomatrix.HTTPError{ + Code: 0, + WrappedError: nil, + Message: lastErr.Error(), + } + } + + logrus.Errorf( + "failed to join user %q to room %q through %d server(s): last error %s", + request.UserID, request.RoomID, len(request.ServerNames), lastErr, ) } diff --git a/federationsender/inthttp/client.go b/federationsender/inthttp/client.go index 5da4b35f..25de99cc 100644 --- a/federationsender/inthttp/client.go +++ b/federationsender/inthttp/client.go @@ -7,6 +7,7 @@ import ( "github.com/matrix-org/dendrite/federationsender/api" "github.com/matrix-org/dendrite/internal/httputil" + "github.com/matrix-org/gomatrix" "github.com/opentracing/opentracing-go" ) @@ -77,12 +78,19 @@ func (h *httpFederationSenderInternalAPI) PerformJoin( ctx context.Context, request *api.PerformJoinRequest, response *api.PerformJoinResponse, -) error { +) { span, ctx := opentracing.StartSpanFromContext(ctx, "PerformJoinRequest") defer span.Finish() apiURL := h.federationSenderURL + FederationSenderPerformJoinRequestPath - return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response) + err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response) + if err != nil { + response.LastError = &gomatrix.HTTPError{ + Message: err.Error(), + Code: 0, + WrappedError: err, + } + } } // Handle an instruction to make_join & send_join with a remote server. diff --git a/federationsender/inthttp/server.go b/federationsender/inthttp/server.go index babd3ae1..a4f3d63d 100644 --- a/federationsender/inthttp/server.go +++ b/federationsender/inthttp/server.go @@ -33,9 +33,7 @@ func AddRoutes(intAPI api.FederationSenderInternalAPI, internalAPIMux *mux.Route if err := json.NewDecoder(req.Body).Decode(&request); err != nil { return util.MessageResponse(http.StatusBadRequest, err.Error()) } - if err := intAPI.PerformJoin(req.Context(), &request, &response); err != nil { - return util.ErrorResponse(err) - } + intAPI.PerformJoin(req.Context(), &request, &response) return util.JSONResponse{Code: http.StatusOK, JSON: &response} }), ) |