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
This commit is contained in:
Kegsay 2020-06-25 15:04:48 +01:00 committed by GitHub
parent c2d34422d6
commit 43cddfe00f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 83 additions and 21 deletions

View file

@ -1,6 +1,7 @@
package api
import (
"encoding/json"
"fmt"
"net/http"
@ -12,8 +13,9 @@ import (
type PerformErrorCode int
type PerformError struct {
Msg string
Code PerformErrorCode
Msg string
RemoteCode int // remote HTTP status code, for PerformErrRemote
Code PerformErrorCode
}
func (p *PerformError) Error() string {
@ -43,6 +45,17 @@ func (p *PerformError) JSONResponse() util.JSONResponse {
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden(p.Msg),
}
case PerformErrRemote:
// if the code is 0 then something bad happened and it isn't
// a remote HTTP error being encapsulated, e.g network error to remote.
if p.RemoteCode == 0 {
return util.ErrorResponse(fmt.Errorf("%s", p.Msg))
}
return util.JSONResponse{
Code: p.RemoteCode,
// TODO: Should we assert this is in fact JSON? E.g gjson parse?
JSON: json.RawMessage(p.Msg),
}
default:
return util.ErrorResponse(p)
}
@ -57,6 +70,8 @@ const (
PerformErrorNoRoom PerformErrorCode = 3
// PerformErrorNoOperation means that the request resulted in nothing happening e.g invite->invite or leave->leave.
PerformErrorNoOperation PerformErrorCode = 4
// PerformErrRemote means that the request failed and the PerformError.Msg is the raw remote JSON error response
PerformErrRemote PerformErrorCode = 5
)
type PerformJoinRequest struct {

View file

@ -270,9 +270,13 @@ func (r *RoomserverInternalAPI) performFederatedJoinRoomByID(
Content: req.Content, // the membership event content
}
fedRes := fsAPI.PerformJoinResponse{}
if err := r.fsAPI.PerformJoin(ctx, &fedReq, &fedRes); err != nil {
return fmt.Errorf("Error joining federated room: %q", err)
r.fsAPI.PerformJoin(ctx, &fedReq, &fedRes)
if fedRes.LastError != nil {
return &api.PerformError{
Code: api.PerformErrRemote,
Msg: fedRes.LastError.Message,
RemoteCode: fedRes.LastError.Code,
}
}
return nil
}