summaryrefslogtreecommitdiffstats
path: root/vendor/maunium.net/go/mautrix/error.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/maunium.net/go/mautrix/error.go')
-rw-r--r--vendor/maunium.net/go/mautrix/error.go154
1 files changed, 154 insertions, 0 deletions
diff --git a/vendor/maunium.net/go/mautrix/error.go b/vendor/maunium.net/go/mautrix/error.go
new file mode 100644
index 00000000..9c5e8a0e
--- /dev/null
+++ b/vendor/maunium.net/go/mautrix/error.go
@@ -0,0 +1,154 @@
+// Copyright (c) 2020 Tulir Asokan
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mautrix
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net/http"
+)
+
+// Common error codes from https://matrix.org/docs/spec/client_server/latest#api-standards
+//
+// Can be used with errors.Is() to check the response code without casting the error:
+//
+// err := client.Sync()
+// if errors.Is(err, MUnknownToken) {
+// // logout
+// }
+var (
+ // Forbidden access, e.g. joining a room without permission, failed login.
+ MForbidden = RespError{ErrCode: "M_FORBIDDEN"}
+ // Unrecognized request, e.g. the endpoint does not exist or is not implemented.
+ MUnrecognized = RespError{ErrCode: "M_UNRECOGNIZED"}
+ // The access token specified was not recognised.
+ MUnknownToken = RespError{ErrCode: "M_UNKNOWN_TOKEN"}
+ // No access token was specified for the request.
+ MMissingToken = RespError{ErrCode: "M_MISSING_TOKEN"}
+ // Request contained valid JSON, but it was malformed in some way, e.g. missing required keys, invalid values for keys.
+ MBadJSON = RespError{ErrCode: "M_BAD_JSON"}
+ // Request did not contain valid JSON.
+ MNotJSON = RespError{ErrCode: "M_NOT_JSON"}
+ // No resource was found for this request.
+ MNotFound = RespError{ErrCode: "M_NOT_FOUND"}
+ // Too many requests have been sent in a short period of time. Wait a while then try again.
+ MLimitExceeded = RespError{ErrCode: "M_LIMIT_EXCEEDED"}
+ // The user ID associated with the request has been deactivated.
+ // Typically for endpoints that prove authentication, such as /login.
+ MUserDeactivated = RespError{ErrCode: "M_USER_DEACTIVATED"}
+ // Encountered when trying to register a user ID which has been taken.
+ MUserInUse = RespError{ErrCode: "M_USER_IN_USE"}
+ // Encountered when trying to register a user ID which is not valid.
+ MInvalidUsername = RespError{ErrCode: "M_INVALID_USERNAME"}
+ // Sent when the room alias given to the createRoom API is already in use.
+ MRoomInUse = RespError{ErrCode: "M_ROOM_IN_USE"}
+ // The state change requested cannot be performed, such as attempting to unban a user who is not banned.
+ MBadState = RespError{ErrCode: "M_BAD_STATE"}
+ // The request or entity was too large.
+ MTooLarge = RespError{ErrCode: "M_TOO_LARGE"}
+ // The resource being requested is reserved by an application service, or the application service making the request has not created the resource.
+ MExclusive = RespError{ErrCode: "M_EXCLUSIVE"}
+ // The client's request to create a room used a room version that the server does not support.
+ MUnsupportedRoomVersion = RespError{ErrCode: "M_UNSUPPORTED_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.
+ MIncompatibleRoomVersion = RespError{ErrCode: "M_INCOMPATIBLE_ROOM_VERSION"}
+ // The client specified a parameter that has the wrong value.
+ MInvalidParam = RespError{ErrCode: "M_INVALID_PARAM"}
+
+ MSC2659URLNotSet = RespError{ErrCode: "FI.MAU.MSC2659_URL_NOT_SET"}
+ MSC2659BadStatus = RespError{ErrCode: "FI.MAU.MSC2659_BAD_STATUS"}
+ MSC2659ConnectionTimeout = RespError{ErrCode: "FI.MAU.MSC2659_CONNECTION_TIMEOUT"}
+ MSC2659ConnectionFailed = RespError{ErrCode: "FI.MAU.MSC2659_CONNECTION_FAILED"}
+)
+
+// HTTPError An HTTP Error response, which may wrap an underlying native Go Error.
+type HTTPError struct {
+ Request *http.Request
+ Response *http.Response
+ ResponseBody string
+
+ WrappedError error
+ RespError *RespError
+ Message string
+}
+
+func (e HTTPError) Is(err error) bool {
+ return (e.RespError != nil && errors.Is(e.RespError, err)) || (e.WrappedError != nil && errors.Is(e.WrappedError, err))
+}
+
+func (e HTTPError) IsStatus(code int) bool {
+ return e.Response != nil && e.Response.StatusCode == code
+}
+
+func (e HTTPError) Error() string {
+ if e.WrappedError != nil {
+ return fmt.Sprintf("%s: %v", e.Message, e.WrappedError)
+ } else if e.RespError != nil {
+ return fmt.Sprintf("failed to %s %s: %s (HTTP %d): %s", e.Request.Method, e.Request.URL.Path,
+ e.RespError.ErrCode, e.Response.StatusCode, e.RespError.Err)
+ } else {
+ msg := fmt.Sprintf("failed to %s %s: %s", e.Request.Method, e.Request.URL.Path, e.Response.Status)
+ if len(e.ResponseBody) > 0 {
+ msg = fmt.Sprintf("%s\n%s", msg, e.ResponseBody)
+ }
+ return msg
+ }
+}
+
+func (e HTTPError) Unwrap() error {
+ if e.WrappedError != nil {
+ return e.WrappedError
+ } else if e.RespError != nil {
+ return *e.RespError
+ }
+ return nil
+}
+
+// RespError is the standard JSON error response from Homeservers. It also implements the Golang "error" interface.
+// See https://spec.matrix.org/v1.2/client-server-api/#api-standards
+type RespError struct {
+ ErrCode string
+ Err string
+ ExtraData map[string]interface{}
+}
+
+func (e *RespError) UnmarshalJSON(data []byte) error {
+ err := json.Unmarshal(data, &e.ExtraData)
+ if err != nil {
+ return err
+ }
+ e.ErrCode, _ = e.ExtraData["errcode"].(string)
+ e.Err, _ = e.ExtraData["error"].(string)
+ return nil
+}
+
+func (e *RespError) MarshalJSON() ([]byte, error) {
+ if e.ExtraData == nil {
+ e.ExtraData = make(map[string]interface{})
+ }
+ e.ExtraData["errcode"] = e.ErrCode
+ e.ExtraData["error"] = e.Err
+ return json.Marshal(&e.ExtraData)
+}
+
+// Error returns the errcode and error message.
+func (e RespError) Error() string {
+ return e.ErrCode + ": " + e.Err
+}
+
+func (e RespError) Is(err error) bool {
+ e2, ok := err.(RespError)
+ if !ok {
+ return false
+ }
+ if e.ErrCode == "M_UNKNOWN" && e2.ErrCode == "M_UNKNOWN" {
+ return e.Err == e2.Err
+ }
+ return e2.ErrCode == e.ErrCode
+}