Add Exceptions
parent
cb3c570c39
commit
206353b583
|
@ -0,0 +1,217 @@
|
|||
module Internal.Values.Exceptions exposing (Error(..), ClientError(..), ServerError(..), errorCatches, errorToString)
|
||||
|
||||
{-| This module contains all potential errors that may be passed around in the SDK.
|
||||
-}
|
||||
|
||||
import Dict
|
||||
import Http
|
||||
import Internal.Tools.DecodeExtra exposing (opField)
|
||||
import Internal.Config.ErrorStrings as ES
|
||||
import Json.Decode as D
|
||||
import Json.Encode as E
|
||||
|
||||
|
||||
type Error
|
||||
= InternetException Http.Error
|
||||
| SDKException ClientError
|
||||
| ServerException ServerError
|
||||
| UnsupportedVersion
|
||||
|
||||
|
||||
{-| Errors that this SDK might return if it doesn't like its own input, if it
|
||||
notices some internal inconsistencies or if it cannot interpret the server's
|
||||
input.
|
||||
|
||||
- `ServerReturnsBadJSON` The homeserver sent JSON that does not parse.
|
||||
- `ServerDoesntFollowJSONSpec` The homeserver sent data that lacks keys
|
||||
required by spec.
|
||||
- `ServerDoesntReturnBaseURL` The homeserver does not clarify its API
|
||||
endpoints.
|
||||
- `CouldntGetTimestamp` The Elm core somehow failed to get the current
|
||||
Unix timestamp.
|
||||
- `InvalidInputAccordingToSpec` The function contains invalid values.
|
||||
|
||||
-}
|
||||
type ClientError
|
||||
= ServerReturnsBadJSON String
|
||||
| CouldntGetTimestamp
|
||||
| InsufficientCredentials String
|
||||
| NotSupportedYet String
|
||||
|
||||
|
||||
{-| Potential error codes that the server may return. If the error is not a
|
||||
default one described in the Matrix Spec, it will be a `CustomServerError`
|
||||
and provide with the custom string.
|
||||
-}
|
||||
type
|
||||
ServerError
|
||||
-- COMMON ERROR CODES
|
||||
-- These error codes can be returned by any API endpoint.
|
||||
-- See https://spec.matrix.org/v1.5/client-server-api/#common-error-codes
|
||||
= M_FORBIDDEN { error : Maybe String }
|
||||
| M_UNKNOWN_TOKEN { error : Maybe String, soft_logout : Maybe Bool }
|
||||
| M_MISSING_TOKEN { error : Maybe String, soft_logout : Maybe Bool }
|
||||
| M_BAD_JSON { error : Maybe String }
|
||||
| M_NOT_JSON { error : Maybe String }
|
||||
| M_NOT_FOUND { error : Maybe String }
|
||||
| M_LIMIT_EXCEEDED { error : Maybe String, retryAfterMs : Maybe Int }
|
||||
| M_UNKNOWN { error : Maybe String }
|
||||
-- OTHER ERROR CODES
|
||||
-- These error codes are specific to certain endpoints.
|
||||
-- See https://spec.matrix.org/v1.4/client-server-api/#other-error-codes
|
||||
| M_UNRECOGNIZED { error : Maybe String }
|
||||
| M_UNAUTHORIZED { error : Maybe String }
|
||||
| M_USER_DEACTIVATED { error : Maybe String }
|
||||
| M_USER_IN_USE { error : Maybe String }
|
||||
| M_INVALID_USERNAME { error : Maybe String }
|
||||
| M_ROOM_IN_USE { error : Maybe String }
|
||||
| M_INVALID_ROOM_STATE { error : Maybe String }
|
||||
| M_THREEPID_IN_USE { error : Maybe String }
|
||||
| M_THREEPID_NOT_FOUND { error : Maybe String }
|
||||
| M_THREEPID_AUTH_FAILED { error : Maybe String }
|
||||
| M_THREEPID_DENIED { error : Maybe String }
|
||||
| M_SERVER_NOT_TRUSTED { error : Maybe String }
|
||||
| M_UNSUPPORTED_ROOM_VERSION { error : Maybe String }
|
||||
| M_INCOMPATIBLE_ROOM_VERSION
|
||||
{ error : Maybe String
|
||||
, room_version : Maybe String
|
||||
}
|
||||
| M_BAD_STATE { error : Maybe String }
|
||||
| M_GUEST_ACCESS_FORBIDDEN { error : Maybe String }
|
||||
| M_CAPTCHA_NEEDED { error : Maybe String }
|
||||
| M_CAPTCHA_INVALID { error : Maybe String }
|
||||
| M_MISSING_PARAM { error : Maybe String }
|
||||
| M_INVALID_PARAM { error : Maybe String }
|
||||
| M_TOO_LARGE { error : Maybe String }
|
||||
| M_EXCLUSIVE { error : Maybe String }
|
||||
| M_RESOURCE_LIMIT_EXCEEDED
|
||||
{ error : Maybe String
|
||||
, adminContact : String
|
||||
}
|
||||
| M_CANNOT_LEAVE_SERVER_NOTICE_ROOM { error : Maybe String }
|
||||
-- Error codes that help understand the server's output
|
||||
| RequiresUserInteractiveAuthentication
|
||||
{ completed : List String
|
||||
, flows : List (List String)
|
||||
, params : Dict.Dict String (Dict.Dict String String)
|
||||
, session : Maybe String
|
||||
}
|
||||
-- CUSTOM ERROR CODES
|
||||
-- These can be defined by custom homeserver implementations
|
||||
| CustomServerError
|
||||
{ errcode : String
|
||||
, fullError : E.Value
|
||||
, statusCode : Int
|
||||
}
|
||||
|
||||
|
||||
{-| Shortcut for the decoder of most errors defined in the Matrix spec
|
||||
-}
|
||||
standardErrorDescription : D.Decoder { error : Maybe String }
|
||||
standardErrorDescription =
|
||||
D.map (\err -> { error = err }) (opField "error" D.string)
|
||||
|
||||
|
||||
{-| Dictionary of known errors that the homeserver may return.
|
||||
The key is the error type, while the value is a function that reads all required
|
||||
and optional fields from the response based on Matrix specifications.
|
||||
-}
|
||||
errorCatches : D.Decoder ServerError
|
||||
errorCatches =
|
||||
D.oneOf
|
||||
[ errorDecoder "M_FORBIDDEN" M_FORBIDDEN standardErrorDescription
|
||||
, errorDecoder "M_UNKNOWN_TOKEN"
|
||||
M_UNKNOWN_TOKEN
|
||||
(D.map2
|
||||
(\err slg -> { error = err, soft_logout = slg })
|
||||
(opField "error" D.string)
|
||||
(opField "soft_logout" D.bool)
|
||||
)
|
||||
, errorDecoder "M_MISSING_TOKEN"
|
||||
M_MISSING_TOKEN
|
||||
(D.map2
|
||||
(\err slg -> { error = err, soft_logout = slg })
|
||||
(opField "error" D.string)
|
||||
(opField "soft_logout" D.bool)
|
||||
)
|
||||
, errorDecoder "M_BAD_JSON" M_BAD_JSON standardErrorDescription
|
||||
, errorDecoder "M_NOT_JSON" M_NOT_JSON standardErrorDescription
|
||||
, errorDecoder "M_NOT_FOUND" M_NOT_FOUND standardErrorDescription
|
||||
, errorDecoder "M_LIMIT_EXCEEDED"
|
||||
M_LIMIT_EXCEEDED
|
||||
(D.map2
|
||||
(\err rams -> { error = err, retryAfterMs = rams })
|
||||
(opField "error" D.string)
|
||||
(opField "retry_after_ms" D.int)
|
||||
)
|
||||
, errorDecoder "M_UNKNOWN" M_UNKNOWN standardErrorDescription
|
||||
, errorDecoder "M_UNRECOGNIZED" M_UNRECOGNIZED standardErrorDescription
|
||||
, errorDecoder "M_UNAUTHORIZED" M_UNAUTHORIZED standardErrorDescription
|
||||
, errorDecoder "M_USER_DEACTIVATED" M_USER_DEACTIVATED standardErrorDescription
|
||||
, errorDecoder "M_USER_IN_USE" M_USER_IN_USE standardErrorDescription
|
||||
, errorDecoder "M_INVALID_USERNAME" M_INVALID_USERNAME standardErrorDescription
|
||||
, errorDecoder "M_ROOM_IN_USE" M_ROOM_IN_USE standardErrorDescription
|
||||
, errorDecoder "M_INVALID_ROOM_STATE" M_INVALID_ROOM_STATE standardErrorDescription
|
||||
, errorDecoder "M_THREEPID_IN_USE" M_THREEPID_IN_USE standardErrorDescription
|
||||
, errorDecoder "M_THREEPID_NOT_FOUND" M_THREEPID_NOT_FOUND standardErrorDescription
|
||||
, errorDecoder "M_THREEPID_AUTH_FAILED" M_THREEPID_AUTH_FAILED standardErrorDescription
|
||||
, errorDecoder "M_THREEPID_DENIED" M_THREEPID_DENIED standardErrorDescription
|
||||
, errorDecoder "M_SERVER_NOT_TRUSTED" M_SERVER_NOT_TRUSTED standardErrorDescription
|
||||
, errorDecoder "M_UNSUPPORTED_ROOM_VERSION" M_UNSUPPORTED_ROOM_VERSION standardErrorDescription
|
||||
, errorDecoder "M_INCOMPATIBLE_ROOM_VERSION"
|
||||
M_INCOMPATIBLE_ROOM_VERSION
|
||||
(D.map2
|
||||
(\err rv -> { error = err, room_version = rv })
|
||||
(opField "error" D.string)
|
||||
(opField "room_version" D.string)
|
||||
)
|
||||
, errorDecoder "M_BAD_STATE" M_BAD_STATE standardErrorDescription
|
||||
, errorDecoder "M_GUEST_ACCESS_FORBIDDEN" M_GUEST_ACCESS_FORBIDDEN standardErrorDescription
|
||||
, errorDecoder "M_CAPTCHA_NEEDED" M_CAPTCHA_NEEDED standardErrorDescription
|
||||
, errorDecoder "M_CAPTCHA_INVALID" M_CAPTCHA_INVALID standardErrorDescription
|
||||
, errorDecoder "M_MISSING_PARAM" M_MISSING_PARAM standardErrorDescription
|
||||
, errorDecoder "M_INVALID_PARAM" M_INVALID_PARAM standardErrorDescription
|
||||
, errorDecoder "M_TOO_LARGE" M_TOO_LARGE standardErrorDescription
|
||||
, errorDecoder "M_EXCLUSIVE" M_EXCLUSIVE standardErrorDescription
|
||||
, errorDecoder "M_RESOURCE_LIMIT_EXCEEDED"
|
||||
M_RESOURCE_LIMIT_EXCEEDED
|
||||
(D.map2
|
||||
(\err ac -> { error = err, adminContact = ac })
|
||||
(opField "error" D.string)
|
||||
(D.field "admin_contact" D.string)
|
||||
)
|
||||
, errorDecoder "M_CANNOT_LEAVE_SERVER_NOTICE_ROOM" M_CANNOT_LEAVE_SERVER_NOTICE_ROOM standardErrorDescription
|
||||
]
|
||||
|
||||
|
||||
errorDecoder : String -> (a -> ServerError) -> D.Decoder a -> D.Decoder ServerError
|
||||
errorDecoder name code decoder =
|
||||
D.field "errcode" D.string
|
||||
|> D.andThen
|
||||
(\errcode ->
|
||||
if errcode == name then
|
||||
D.map code decoder
|
||||
|
||||
else
|
||||
D.fail "Not the right errcode"
|
||||
)
|
||||
|
||||
|
||||
errorToString : Error -> String
|
||||
errorToString e =
|
||||
case e of
|
||||
UnsupportedVersion ->
|
||||
ES.unsupportedVersion
|
||||
|
||||
SDKException (ServerReturnsBadJSON s) ->
|
||||
ES.serverReturnsBadJSON s
|
||||
|
||||
SDKException CouldntGetTimestamp ->
|
||||
ES.couldNotGetTimestamp
|
||||
|
||||
ServerException (M_FORBIDDEN data) ->
|
||||
ES.serverSaysForbidden data.error
|
||||
|
||||
-- ServerError (M_UNKNOWN_TOKEN data) ->
|
||||
_ ->
|
||||
"ERROR NEEDS STRING"
|
Loading…
Reference in New Issue