Make models.ApiError interface, not struct

This commit is contained in:
nxshock 2019-08-03 11:46:57 +05:00
parent a2ebc64065
commit 87144ee37d
9 changed files with 151 additions and 121 deletions

View File

@ -9,12 +9,12 @@ import (
)
type Backend interface {
Register(username, password, device string) (user User, token string, err *models.ApiError)
Login(username, password, device string) (user User, token string, err *models.ApiError)
Register(username, password, device string) (user User, token string, err models.ApiError)
Login(username, password, device string) (user User, token string, err models.ApiError)
GetUserByToken(token string) (user User)
GetUserByName(userName string) User
GetRoomByID(id string) Room
Sync(token string, request sync.SyncRequest) (response *sync.SyncReply, err *models.ApiError)
Sync(token string, request sync.SyncRequest) (response *sync.SyncReply, err models.ApiError)
PublicRooms() []Room
}
@ -37,15 +37,15 @@ type User interface {
Name() string
ID() string
Password() string
CreateRoom(request createroom.Request) (Room, *models.ApiError)
LeaveRoom(room Room) *models.ApiError
SetTopic(room Room, topic string) *models.ApiError
SendMessage(room Room, text string) *models.ApiError
CreateRoom(request createroom.Request) (Room, models.ApiError)
LeaveRoom(room Room) models.ApiError
SetTopic(room Room, topic string) models.ApiError
SendMessage(room Room, text string) models.ApiError
JoinedRooms() []Room
ChangePassword(newPassword string)
Devices() []devices.Device
SetRoomVisibility(Room, createroom.VisibilityType) *models.ApiError
SetRoomVisibility(Room, createroom.VisibilityType) models.ApiError
Logout(token string)
LogoutAll()
JoinRoom(Room) *models.ApiError
JoinRoom(Room) models.ApiError
}

View File

@ -29,12 +29,12 @@ func NewBackend(hostname string) *Backend {
data: make(map[string]internal.User)}
}
func (backend *Backend) Register(username, password, device string) (user internal.User, token string, err *models.ApiError) {
func (backend *Backend) Register(username, password, device string) (user internal.User, token string, err models.ApiError) {
backend.mutex.Lock()
if _, ok := backend.data[username]; ok {
backend.mutex.Unlock()
return nil, "", internal.NewError(models.M_USER_IN_USE, "trying to register a user ID which has been taken")
return nil, "", models.NewError(models.M_USER_IN_USE, "trying to register a user ID which has been taken")
}
user = &User{
@ -49,17 +49,17 @@ func (backend *Backend) Register(username, password, device string) (user intern
return backend.Login(username, password, device)
}
func (backend *Backend) Login(username, password, device string) (user internal.User, token string, err *models.ApiError) {
func (backend *Backend) Login(username, password, device string) (user internal.User, token string, err models.ApiError) {
backend.mutex.Lock()
defer backend.mutex.Unlock()
user, ok := backend.data[username]
if !ok {
return nil, "", internal.NewError(models.M_FORBIDDEN, "wrong username")
return nil, "", models.NewError(models.M_FORBIDDEN, "wrong username")
}
if user.Password() != password {
return nil, "", internal.NewError(models.M_FORBIDDEN, "wrong password")
return nil, "", models.NewError(models.M_FORBIDDEN, "wrong password")
}
token = newToken(defaultTokenSize)
@ -69,7 +69,7 @@ func (backend *Backend) Login(username, password, device string) (user internal.
return user, token, nil
}
func (backend *Backend) Sync(token string, request mSync.SyncRequest) (response *mSync.SyncReply, err *models.ApiError) {
func (backend *Backend) Sync(token string, request mSync.SyncRequest) (response *mSync.SyncReply, err models.ApiError) {
backend.mutex.Lock()
defer backend.mutex.Unlock()

View File

@ -18,7 +18,7 @@ func TestRegisterUser(t *testing.T) {
)
user, token, err := backend.Register(username, password, device)
assert.Nil(t, err)
assert.NoError(t, err)
assert.Equal(t, username, user.Name())
assert.Equal(t, password, user.Password())
assert.NotEmpty(t, token)
@ -32,7 +32,7 @@ func TestRegisterUserWithAlreadyTakenName(t *testing.T) {
)
_, _, err := backend.Register(userName, "", "")
assert.Nil(t, err)
assert.NoError(t, err)
_, _, err = backend.Register(userName, "", "")
assert.NotNil(t, err)
@ -47,10 +47,10 @@ func TestLogin(t *testing.T) {
)
_, _, err := backend.Register(userName, password, "")
assert.Nil(t, err)
assert.NoError(t, err)
_, token, err := backend.Login(userName, password, "")
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotZero(t, token)
}
@ -63,7 +63,7 @@ func TestLoginWithWrongCredentials(t *testing.T) {
)
_, _, err := backend.Register(userName, password, "")
assert.Nil(t, err)
assert.NoError(t, err)
_, _, err = backend.Login(userName, "wrong password", "")
assert.NotNil(t, err)
@ -81,10 +81,10 @@ func TestLogout(t *testing.T) {
)
user, _, err := backend.Register(userName, password, "")
assert.Nil(t, err)
assert.NoError(t, err)
_, token, err := backend.Login(userName, password, "")
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotZero(t, token)
user.Logout(token)
@ -96,7 +96,7 @@ func TestGetRoomByID(t *testing.T) {
backend := NewBackend("localhost")
user, token, err := backend.Register("user", "", "")
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotNil(t, user)
assert.NotEmpty(t, token)
@ -105,7 +105,7 @@ func TestGetRoomByID(t *testing.T) {
Name: "room1"}
room, err := user.CreateRoom(request)
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotNil(t, room)
assert.Equal(t, room.ID(), backend.GetRoomByID(room.ID()).ID())
@ -122,7 +122,7 @@ func TestGetUserByName(t *testing.T) {
)
user, token, err := backend.Register(userName, "", "")
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotNil(t, user)
assert.NotEmpty(t, token)
@ -141,7 +141,7 @@ func TestPublicRooms(t *testing.T) {
backend := NewBackend("localhost")
user1, _, err := backend.Register("user1", "", "")
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotNil(t, user1)
// Create first room
@ -151,7 +151,7 @@ func TestPublicRooms(t *testing.T) {
Preset: createroom.PublicChat}
room1, err := user1.CreateRoom(request)
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotNil(t, room1)
// Create second room
@ -161,16 +161,16 @@ func TestPublicRooms(t *testing.T) {
Preset: createroom.PublicChat}
room2, err := user1.CreateRoom(request)
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotNil(t, room2)
// Make room2 has 2 users
user2, _, err := backend.Register("user2", "", "")
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotNil(t, user2)
err = user2.JoinRoom(room2)
assert.Nil(t, err)
assert.NoError(t, err)
rooms := backend.PublicRooms()
assert.Len(t, rooms, 2)

View File

@ -12,7 +12,7 @@ func TestCreateRoom(t *testing.T) {
backend := NewBackend("localhost")
user, _, err := backend.Register("user1", "", "")
assert.Nil(t, err)
assert.NoError(t, err)
request := createroom.Request{
RoomAliasName: "room1",
@ -20,7 +20,7 @@ func TestCreateRoom(t *testing.T) {
Topic: "topic"}
room, err := user.CreateRoom(request)
assert.Nil(t, err)
assert.NoError(t, err)
assert.Equal(t, request.RoomAliasName, room.AliasName())
assert.Equal(t, request.Name, room.Name())
assert.Equal(t, request.Topic, room.Topic())
@ -40,7 +40,7 @@ func TestCreateAlreadyExistingRoom(t *testing.T) {
Topic: "topic"}
_, err := user.CreateRoom(request)
assert.Nil(t, err)
assert.NoError(t, err)
_, err = user.CreateRoom(request)
assert.NotNil(t, err)
@ -60,7 +60,7 @@ func TestSetRoomTopic(t *testing.T) {
var newTopic = "new topic"
err := user.SetTopic(room, newTopic)
assert.Nil(t, err)
assert.NoError(t, err)
assert.Equal(t, newTopic, room.Topic())
assert.Equal(t, 5, len(room.Events())) // TODO: check start event count
}
@ -109,7 +109,7 @@ func TestRoomUserCount(t *testing.T) {
backend := NewBackend("localhost")
user1, _, err := backend.Register("user1", "", "")
assert.Nil(t, err)
assert.NoError(t, err)
request := createroom.Request{
RoomAliasName: "room1",
@ -117,7 +117,7 @@ func TestRoomUserCount(t *testing.T) {
Topic: "topic"}
room, err := user1.CreateRoom(request)
assert.Nil(t, err)
assert.NoError(t, err)
assert.Len(t, room.Users(), 1)
// TODO: add join another user test

View File

@ -33,10 +33,10 @@ func (user *User) Password() string {
return user.password
}
func (user *User) CreateRoom(request createroom.Request) (internal.Room, *models.ApiError) {
func (user *User) CreateRoom(request createroom.Request) (internal.Room, models.ApiError) {
for _, existingRoom := range user.backend.rooms {
if existingRoom.AliasName() == request.RoomAliasName { // TODO: strip and check request room alias name before use
return nil, internal.NewError(models.M_ROOM_IN_USE, "")
return nil, models.NewError(models.M_ROOM_IN_USE, "")
}
}
@ -104,12 +104,12 @@ func (user *User) CreateRoom(request createroom.Request) (internal.Room, *models
return room, nil
}
func (user *User) SetTopic(room internal.Room, topic string) *models.ApiError {
func (user *User) SetTopic(room internal.Room, topic string) models.ApiError {
room.(*Room).mutex.Lock()
defer room.(*Room).mutex.Unlock()
if room.(*Room).creator.ID() != user.ID() { // TODO: currently only creator can change topic
return internal.NewError(models.M_FORBIDDEN, "")
return models.NewError(models.M_FORBIDDEN, "")
}
room.(*Room).topic = topic
@ -122,7 +122,7 @@ func (user *User) SetTopic(room internal.Room, topic string) *models.ApiError {
return nil
}
func (user *User) LeaveRoom(room internal.Room) *models.ApiError {
func (user *User) LeaveRoom(room internal.Room) models.ApiError {
room.(*Room).mutex.Lock()
defer room.(*Room).mutex.Unlock()
@ -133,10 +133,10 @@ func (user *User) LeaveRoom(room internal.Room) *models.ApiError {
}
}
return internal.NewError(models.M_BAD_STATE, "you are not a member of group") // TODO: check error code
return models.NewError(models.M_BAD_STATE, "you are not a member of group") // TODO: check error code
}
func (user *User) SendMessage(room internal.Room, text string) *models.ApiError {
func (user *User) SendMessage(room internal.Room, text string) models.ApiError {
room.(*Room).mutex.Lock()
defer room.(*Room).mutex.Unlock()
@ -148,7 +148,7 @@ func (user *User) SendMessage(room internal.Room, text string) *models.ApiError
}
if !userInRoom {
return internal.NewError(models.M_FORBIDDEN, "")
return models.NewError(models.M_FORBIDDEN, "")
}
room.(*Room).events = append(room.(*Room).events, RoomEvent{
@ -195,9 +195,9 @@ func (user *User) Devices() []devices.Device {
return result
}
func (user *User) SetRoomVisibility(room internal.Room, visibilityType createroom.VisibilityType) *models.ApiError {
func (user *User) SetRoomVisibility(room internal.Room, visibilityType createroom.VisibilityType) models.ApiError {
if user.ID() != room.Creator().ID() {
return internal.NewError(models.M_FORBIDDEN, "only room owner can change visibility") // TODO: room administrators can use this method too
return models.NewError(models.M_FORBIDDEN, "only room owner can change visibility") // TODO: room administrators can use this method too
}
room.(*Room).mutex.Lock()
@ -223,7 +223,7 @@ func (user *User) LogoutAll() {
user.Tokens = make(map[string]Token)
}
func (user *User) JoinRoom(room internal.Room) *models.ApiError {
func (user *User) JoinRoom(room internal.Room) models.ApiError {
memRoom := room.(*Room)
memRoom.mutex.Lock()
@ -231,7 +231,7 @@ func (user *User) JoinRoom(room internal.Room) *models.ApiError {
for _, roomUser := range memRoom.joined {
if roomUser.ID() == user.ID() {
return internal.NewError(models.M_BAD_STATE, "user already in room") // TODO: check code
return models.NewError(models.M_BAD_STATE, "user already in room") // TODO: check code
}
}

View File

@ -19,7 +19,7 @@ func TestUserID(t *testing.T) {
backend := NewBackend(hostName)
user, _, err := backend.Register(userName, "", "")
assert.Nil(t, err)
assert.NoError(t, err)
assert.Equal(t, expectedUserID, user.ID())
}
@ -28,34 +28,34 @@ func TestUserMessage(t *testing.T) {
backend := NewBackend("localhost")
user, _, err := backend.Register("user1", "", "")
assert.Nil(t, err)
assert.NoError(t, err)
request := createroom.Request{
RoomAliasName: "room1",
Name: "room1"}
room, err := user.CreateRoom(request)
assert.Nil(t, err)
assert.NoError(t, err)
err = user.SendMessage(room, "hello")
assert.Nil(t, err)
assert.NoError(t, err)
}
func TestUserMessageInWrongRoom(t *testing.T) {
backend := NewBackend("localhost")
user1, _, err := backend.Register("user1", "", "")
assert.Nil(t, err)
assert.NoError(t, err)
request := createroom.Request{
RoomAliasName: "room1",
Name: "room1"}
room, err := user1.CreateRoom(request)
assert.Nil(t, err)
assert.NoError(t, err)
user2, _, err := backend.Register("user2", "", "")
assert.Nil(t, err)
assert.NoError(t, err)
err = user2.SendMessage(room, "hello")
assert.NotNil(t, err)
@ -65,7 +65,7 @@ func TestGetUserByToken(t *testing.T) {
backend := NewBackend("localhost")
user, token, err := backend.Register("user1", "", "")
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotEmpty(t, token)
gotUser := backend.GetUserByToken(token)
@ -76,7 +76,7 @@ func TestGetUserByWrongToken(t *testing.T) {
backend := NewBackend("localhost")
_, token, err := backend.Register("user1", "", "")
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotEmpty(t, token)
gotUser := backend.GetUserByToken("wrong token")
@ -92,10 +92,10 @@ func TestLogoutWithWrongToken(t *testing.T) {
)
user, _, err := backend.Register(userName, password, "")
assert.Nil(t, err)
assert.NoError(t, err)
_, token, err := backend.Login(userName, password, "")
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotZero(t, token)
user.Logout("worng token")
@ -105,7 +105,7 @@ func TestJoinedRooms(t *testing.T) {
backend := NewBackend("localhost")
user, _, err := backend.Register("user1", "", "")
assert.Nil(t, err)
assert.NoError(t, err)
request := createroom.Request{
RoomAliasName: "room1",
@ -113,7 +113,7 @@ func TestJoinedRooms(t *testing.T) {
Topic: "topic"}
room, err := user.CreateRoom(request)
assert.Nil(t, err)
assert.NoError(t, err)
rooms := user.JoinedRooms()
assert.Equal(t, []internal.Room{room}, rooms)
@ -125,7 +125,7 @@ func TestNewPassword(t *testing.T) {
var newPassword = "new password"
user, _, err := backend.Register("user1", "old password", "")
assert.Nil(t, err)
assert.NoError(t, err)
user.ChangePassword(newPassword)
assert.Equal(t, newPassword, user.Password())
@ -137,7 +137,7 @@ func TestDevices(t *testing.T) {
var expectedDeviceID = "my device"
user, _, err := backend.Register("user1", "", expectedDeviceID)
assert.Nil(t, err)
assert.NoError(t, err)
devices := user.Devices()
assert.Len(t, devices, 1)
@ -148,7 +148,7 @@ func TestSetRoomVisibility(t *testing.T) {
backend := NewBackend("localhost")
user, _, err := backend.Register("user1", "", "")
assert.Nil(t, err)
assert.NoError(t, err)
request := createroom.Request{
RoomAliasName: "room1",
@ -156,17 +156,17 @@ func TestSetRoomVisibility(t *testing.T) {
Visibility: createroom.VisibilityTypePrivate}
room, err := user.CreateRoom(request)
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotNil(t, room)
assert.Equal(t, createroom.VisibilityTypePrivate, room.Visibility())
err = user.SetRoomVisibility(room, createroom.VisibilityTypePublic)
assert.Nil(t, err)
assert.NoError(t, err)
assert.Equal(t, createroom.VisibilityTypePublic, room.Visibility())
// TODO: Only owner can change room visibility
notOwnerUser, _, err := backend.Register("user2", "", "")
assert.Nil(t, err)
assert.NoError(t, err)
err = notOwnerUser.SetRoomVisibility(room, createroom.VisibilityTypePrivate)
assert.NotNil(t, err)
@ -182,11 +182,11 @@ func TestLogoutAll(t *testing.T) {
)
user, _, err := backend.Register(userName, password, "dev1")
assert.Nil(t, err)
assert.NoError(t, err)
assert.Len(t, user.Devices(), 1)
_, _, err = backend.Login(userName, password, "dev2")
assert.Nil(t, err)
assert.NoError(t, err)
assert.Len(t, user.Devices(), 2)
user.LogoutAll()

View File

@ -6,21 +6,14 @@ import (
"github.com/nxshock/signaller/internal/models"
)
func errorResponse(w http.ResponseWriter, code models.ApiError, httpCode int, message string) {
func errorResponse(w http.ResponseWriter, code models.ApiError, httpCode int, messageOverride string) {
w.Header().Set("Content-Type", "application/json")
if message != "" {
code.Message = message
}
w.WriteHeader(httpCode)
if messageOverride != "" {
w.Write(models.NewError(code, messageOverride).JSON())
} else {
w.Write(code.JSON())
}
func NewError(code models.ApiError, message string) *models.ApiError {
if message != "" {
code.Message = message
}
return &code
}

View File

@ -68,7 +68,7 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
_, token, apiErr := currServer.Backend.Login(request.Identifier.User, request.Password, request.DeviceID)
if apiErr != nil {
errorResponse(w, *apiErr, http.StatusForbidden, "")
errorResponse(w, apiErr, http.StatusForbidden, "")
return
}
@ -110,7 +110,7 @@ func leaveRoomHandler(w http.ResponseWriter, r *http.Request) {
err := user.LeaveRoom(room)
if err != nil {
errorResponse(w, *err, http.StatusBadRequest, "")
errorResponse(w, err, http.StatusBadRequest, "")
return
}
@ -185,7 +185,7 @@ func RegisterHandler(w http.ResponseWriter, r *http.Request) {
_, token, apiErr := currServer.Backend.Register(request.Username, request.Password, request.DeviceID)
if apiErr != nil {
errorResponse(w, *apiErr, http.StatusBadRequest, "")
errorResponse(w, apiErr, http.StatusBadRequest, "")
return
}

View File

@ -4,49 +4,86 @@ import (
"encoding/json"
)
type ApiError struct {
Code string `json:"errcode"`
Message string `json:"error"`
type ApiError interface {
error
Code() string
Message() string
JSON() []byte
}
type apiError struct {
code string `json:"errcode"`
message string `json:"error"`
}
func (apiError *apiError) Error() string {
s := apiError.code
if apiError.message != "" {
s = s + ": " + apiError.message
}
return s
}
func (apiError *apiError) Code() string {
return apiError.code
}
func (apiError *apiError) Message() string {
return apiError.message
}
func (apiError *apiError) JSON() []byte {
b, _ := json.Marshal(apiError) // TODO: error handler?
return b
}
var (
// https://matrix.org/docs/spec/client_server/latest#api-standards
M_FORBIDDEN = ApiError{"M_FORBIDDEN", ""} // Forbidden access, e.g. joining a room without permission, failed login.
M_UNKNOWN_TOKEN = ApiError{"M_UNKNOWN_TOKEN", ""} // The access token specified was not recognised.
M_MISSING_TOKEN = ApiError{"M_MISSING_TOKEN", ""} // No access token was specified for the request.
M_BAD_JSON = ApiError{"M_BAD_JSON", ""} // Request contained valid JSON, but it was malformed in some way, e.g. missing required keys, invalid values for keys.
M_NOT_JSON = ApiError{"M_NOT_JSON", ""} // Request did not contain valid JSON.
M_NOT_FOUND = ApiError{"M_NOT_FOUND", ""} // No resource was found for this request.
M_LIMIT_EXCEEDED = ApiError{"M_LIMIT_EXCEEDED", ""} // Too many requests have been sent in a short period of time. Wait a while then try again.
M_UNKNOWN = ApiError{"M_UNKNOWN", ""} // An unknown error has occurred.
M_FORBIDDEN = &apiError{"M_FORBIDDEN", ""} // Forbidden access, e.g. joining a room without permission, failed login.
M_UNKNOWN_TOKEN = &apiError{"M_UNKNOWN_TOKEN", ""} // The access token specified was not recognised.
M_MISSING_TOKEN = &apiError{"M_MISSING_TOKEN", ""} // No access token was specified for the request.
M_BAD_JSON = &apiError{"M_BAD_JSON", ""} // Request contained valid JSON, but it was malformed in some way, e.g. missing required keys, invalid values for keys.
M_NOT_JSON = &apiError{"M_NOT_JSON", ""} // Request did not contain valid JSON.
M_NOT_FOUND = &apiError{"M_NOT_FOUND", ""} // No resource was found for this request.
M_LIMIT_EXCEEDED = &apiError{"M_LIMIT_EXCEEDED", ""} // Too many requests have been sent in a short period of time. Wait a while then try again.
M_UNKNOWN = &apiError{"M_UNKNOWN", ""} // An unknown error has occurred.
M_UNRECOGNIZED = ApiError{"M_UNRECOGNIZED", ""} // The server did not understand the request.
M_UNAUTHORIZED = ApiError{"M_UNAUTHORIZED", ""} // The request was not correctly authorized. Usually due to login failures.
M_USER_IN_USE = ApiError{"M_USER_IN_USE", ""} // Encountered when trying to register a user ID which has been taken.
M_INVALID_USERNAME = ApiError{"M_INVALID_USERNAME", ""} // Encountered when trying to register a user ID which is not valid.
M_ROOM_IN_USE = ApiError{"M_ROOM_IN_USE", ""} // Sent when the room alias given to the createRoom API is already in use.
M_INVALID_ROOM_STATE = ApiError{"M_INVALID_ROOM_STATE", ""} // Sent when the initial state given to the createRoom API is invalid.
M_THREEPID_IN_USE = ApiError{"M_THREEPID_IN_USE", ""} // Sent when a threepid given to an API cannot be used because the same threepid is already in use.
M_THREEPID_NOT_FOUND = ApiError{"M_THREEPID_NOT_FOUND", ""} // Sent when a threepid given to an API cannot be used because no record matching the threepid was found.
M_THREEPID_AUTH_FAILED = ApiError{"M_THREEPID_AUTH_FAILED", ""} // Authentication could not be performed on the third party identifier.
M_THREEPID_DENIED = ApiError{"M_THREEPID_DENIED", ""} // The server does not permit this third party identifier. This may happen if the server only permits, for example, email addresses from a particular domain.
M_SERVER_NOT_TRUSTED = ApiError{"M_SERVER_NOT_TRUSTED", ""} // The client's request used a third party server, eg. identity server, that this server does not trust.
M_UNSUPPORTED_ROOM_VERSION = ApiError{"M_UNSUPPORTED_ROOM_VERSION", ""} // The client's request to create a room used a room version that the server does not support.
M_INCOMPATIBLE_ROOM_VERSION = ApiError{"M_INCOMPATIBLE_ROOM_VERSION", ""} // The client attempted to join a room that has a version the server does not support. Inspect the room_version property of the error response for the room's version.
M_BAD_STATE = ApiError{"M_BAD_STATE", ""} // The state change requested cannot be performed, such as attempting to unban a user who is not banned.
M_GUEST_ACCESS_FORBIDDEN = ApiError{"M_GUEST_ACCESS_FORBIDDEN", ""} // The room or resource does not permit guests to access it.
M_CAPTCHA_NEEDED = ApiError{"M_CAPTCHA_NEEDED", ""} // A Captcha is required to complete the request.
M_CAPTCHA_INVALID = ApiError{"M_CAPTCHA_INVALID", ""} // The Captcha provided did not match what was expected.
M_MISSING_PARAM = ApiError{"M_MISSING_PARAM", ""} // A required parameter was missing from the request.
M_INVALID_PARAM = ApiError{"M_INVALID_PARAM", ""} // A parameter that was specified has the wrong value. For example, the server expected an integer and instead received a string.
M_TOO_LARGE = ApiError{"M_TOO_LARGE", ""} // The request or entity was too large.
M_EXCLUSIVE = ApiError{"M_EXCLUSIVE", ""} // The resource being requested is reserved by an application service, or the application service making the request has not created the resource.
M_RESOURCE_LIMIT_EXCEEDED = ApiError{"M_RESOURCE_LIMIT_EXCEEDED", ""} // The request cannot be completed because the homeserver has reached a resource limit imposed on it. For example, a homeserver held in a shared hosting environment may reach a resource limit if it starts using too much memory or disk space. The error MUST have an admin_contact field to provide the user receiving the error a place to reach out to. Typically, this error will appear on routes which attempt to modify state (eg: sending messages, account data, etc) and not routes which only read state (eg: /sync, get account data, etc).
M_CANNOT_LEAVE_SERVER_NOTICE_ROOM = ApiError{"M_CANNOT_LEAVE_SERVER_NOTICE_ROOM", ""} // The user is unable to reject an invite to join the server notices room. See the Server Notices module for more information.
M_UNRECOGNIZED = &apiError{"M_UNRECOGNIZED", ""} // The server did not understand the request.
M_UNAUTHORIZED = &apiError{"M_UNAUTHORIZED", ""} // The request was not correctly authorized. Usually due to login failures.
M_USER_IN_USE = &apiError{"M_USER_IN_USE", ""} // Encountered when trying to register a user ID which has been taken.
M_INVALID_USERNAME = &apiError{"M_INVALID_USERNAME", ""} // Encountered when trying to register a user ID which is not valid.
M_ROOM_IN_USE = &apiError{"M_ROOM_IN_USE", ""} // Sent when the room alias given to the createRoom API is already in use.
M_INVALID_ROOM_STATE = &apiError{"M_INVALID_ROOM_STATE", ""} // Sent when the initial state given to the createRoom API is invalid.
M_THREEPID_IN_USE = &apiError{"M_THREEPID_IN_USE", ""} // Sent when a threepid given to an API cannot be used because the same threepid is already in use.
M_THREEPID_NOT_FOUND = &apiError{"M_THREEPID_NOT_FOUND", ""} // Sent when a threepid given to an API cannot be used because no record matching the threepid was found.
M_THREEPID_AUTH_FAILED = &apiError{"M_THREEPID_AUTH_FAILED", ""} // Authentication could not be performed on the third party identifier.
M_THREEPID_DENIED = &apiError{"M_THREEPID_DENIED", ""} // The server does not permit this third party identifier. This may happen if the server only permits, for example, email addresses from a particular domain.
M_SERVER_NOT_TRUSTED = &apiError{"M_SERVER_NOT_TRUSTED", ""} // The client's request used a third party server, eg. identity server, that this server does not trust.
M_UNSUPPORTED_ROOM_VERSION = &apiError{"M_UNSUPPORTED_ROOM_VERSION", ""} // The client's request to create a room used a room version that the server does not support.
M_INCOMPATIBLE_ROOM_VERSION = &apiError{"M_INCOMPATIBLE_ROOM_VERSION", ""} // The client attempted to join a room that has a version the server does not support. Inspect the room_version property of the error response for the room's version.
M_BAD_STATE = &apiError{"M_BAD_STATE", ""} // The state change requested cannot be performed, such as attempting to unban a user who is not banned.
M_GUEST_ACCESS_FORBIDDEN = &apiError{"M_GUEST_ACCESS_FORBIDDEN", ""} // The room or resource does not permit guests to access it.
M_CAPTCHA_NEEDED = &apiError{"M_CAPTCHA_NEEDED", ""} // A Captcha is required to complete the request.
M_CAPTCHA_INVALID = &apiError{"M_CAPTCHA_INVALID", ""} // The Captcha provided did not match what was expected.
M_MISSING_PARAM = &apiError{"M_MISSING_PARAM", ""} // A required parameter was missing from the request.
M_INVALID_PARAM = &apiError{"M_INVALID_PARAM", ""} // A parameter that was specified has the wrong value. For example, the server expected an integer and instead received a string.
M_TOO_LARGE = &apiError{"M_TOO_LARGE", ""} // The request or entity was too large.
M_EXCLUSIVE = &apiError{"M_EXCLUSIVE", ""} // The resource being requested is reserved by an application service, or the application service making the request has not created the resource.
M_RESOURCE_LIMIT_EXCEEDED = &apiError{"M_RESOURCE_LIMIT_EXCEEDED", ""} // The request cannot be completed because the homeserver has reached a resource limit imposed on it. For example, a homeserver held in a shared hosting environment may reach a resource limit if it starts using too much memory or disk space. The error MUST have an admin_contact field to provide the user receiving the error a place to reach out to. Typically, this error will appear on routes which attempt to modify state (eg: sending messages, account data, etc) and not routes which only read state (eg: /sync, get account data, etc).
M_CANNOT_LEAVE_SERVER_NOTICE_ROOM = &apiError{"M_CANNOT_LEAVE_SERVER_NOTICE_ROOM", ""} // The user is unable to reject an invite to join the server notices room. See the Server Notices module for more information.
)
func (apiError ApiError) JSON() []byte {
b, _ := json.Marshal(apiError) // TODO: error handler?
return b
func NewError(err ApiError, messageOverride string) ApiError {
newErr := &apiError{
code: err.Code(),
message: err.Message()}
if messageOverride != "" {
newErr.message = messageOverride
}
return newErr
}