aboutsummaryrefslogtreecommitdiff
path: root/federationsender
diff options
context:
space:
mode:
authorKegsay <kegan@matrix.org>2020-06-25 15:04:48 +0100
committerGitHub <noreply@github.com>2020-06-25 15:04:48 +0100
commit43cddfe00f53e3a2df4769be31c66cd818a2966e (patch)
treed7947effce9b38e94f04fce7adda71d0195c021f /federationsender
parentc2d34422d65e81eee6e9d0c31a4c5a446fa9678a (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.go4
-rw-r--r--federationsender/internal/perform.go28
-rw-r--r--federationsender/inthttp/client.go12
-rw-r--r--federationsender/inthttp/server.go4
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}
}),
)