From c844c94564e517406e220d7afeb5a5e904554cd4 Mon Sep 17 00:00:00 2001 From: Bram van den Heuvel Date: Tue, 21 Feb 2023 16:57:58 +0100 Subject: [PATCH] Finish files before API end functions refactor --- src/Internal/Api/All.elm | 2 + src/Internal/Api/Helpers.elm | 51 ++++++++++++---------- src/Internal/Api/SendMessageEvent/Main.elm | 1 + src/Internal/Api/SendStateKey/Main.elm | 1 + src/Internal/Config/ErrorStrings.elm | 2 +- src/Internal/Tools/Exceptions.elm | 14 +++--- src/Internal/Tools/Timestamp.elm | 13 +++++- src/Internal/Tools/VersionControl.elm | 17 ++++++++ 8 files changed, 70 insertions(+), 31 deletions(-) diff --git a/src/Internal/Api/All.elm b/src/Internal/Api/All.elm index 3cef9f0..b0394d9 100644 --- a/src/Internal/Api/All.elm +++ b/src/Internal/Api/All.elm @@ -9,9 +9,11 @@ import Internal.Api.Versions.Main as Versions import Internal.Tools.Exceptions as X import Task exposing (Task) + type alias Future a = Task X.Error a + {-| Get a specific event from the Matrix API. -} getEvent : List String -> Maybe (GetEvent.EventInput -> Future GetEvent.EventOutput) diff --git a/src/Internal/Api/Helpers.elm b/src/Internal/Api/Helpers.elm index eb428ea..108f11c 100644 --- a/src/Internal/Api/Helpers.elm +++ b/src/Internal/Api/Helpers.elm @@ -1,9 +1,10 @@ module Internal.Api.Helpers exposing (..) +import Http import Internal.Tools.Exceptions as X import Process import Task exposing (Task) -import Http + {-| Sometimes, a URL endpoint might be ratelimited. In such a case, the homeserver tells the SDK to wait for a while and then send its response again. @@ -11,40 +12,42 @@ the homeserver tells the SDK to wait for a while and then send its response agai ratelimited : Task X.Error a -> Task X.Error a ratelimited task = task - |> Task.onError - (\e -> - case e of - X.ServerException (X.M_LIMIT_EXCEEDED { retryAfterMs }) -> - case retryAfterMs of - Just interval -> - interval - |> (+) 1 - |> toFloat + |> Task.onError + (\e -> + case e of + X.ServerException (X.M_LIMIT_EXCEEDED { retryAfterMs }) -> + case retryAfterMs of + Just interval -> + interval + |> (+) 1 + |> toFloat + |> Process.sleep + |> Task.andThen (\_ -> task) + |> ratelimited + + Nothing -> + Task.fail e + + X.InternetException (Http.BadStatus 429) -> + 1000 |> Process.sleep |> Task.andThen (\_ -> task) |> ratelimited - Nothing -> - Task.fail e - - X.InternetException (Http.BadStatus 429) -> - 1000 - |> Process.sleep - |> Task.andThen (\_ -> task) - |> ratelimited - - _ -> - Task.fail e - ) + _ -> + Task.fail e + ) + {-| Sometimes, you don't really care if something went wrong - you just want to try again. This task will only return an error if it went wrong on the n'th attempt. + -} retryTask : Int -> Task x a -> Task x a retryTask n task = if n <= 0 then task - else - Task.onError (\_ -> retryTask (n - 1) task ) task + else + Task.onError (\_ -> retryTask (n - 1) task) task diff --git a/src/Internal/Api/SendMessageEvent/Main.elm b/src/Internal/Api/SendMessageEvent/Main.elm index f34206e..e8f161e 100644 --- a/src/Internal/Api/SendMessageEvent/Main.elm +++ b/src/Internal/Api/SendMessageEvent/Main.elm @@ -5,6 +5,7 @@ import Internal.Tools.Exceptions as X import Internal.Tools.VersionControl as VC import Task exposing (Task) + sendMessageEvent : List String -> Maybe (SendMessageEventInput -> Task X.Error SendMessageEventOutput) sendMessageEvent versions = VC.withBottomLayer diff --git a/src/Internal/Api/SendStateKey/Main.elm b/src/Internal/Api/SendStateKey/Main.elm index e923fb0..f944d87 100644 --- a/src/Internal/Api/SendStateKey/Main.elm +++ b/src/Internal/Api/SendStateKey/Main.elm @@ -5,6 +5,7 @@ import Internal.Tools.Exceptions as X import Internal.Tools.VersionControl as VC import Task exposing (Task) + sendStateKey : List String -> Maybe (SendStateKeyInput -> Task X.Error SendStateKeyOutput) sendStateKey versions = VC.withBottomLayer diff --git a/src/Internal/Config/ErrorStrings.elm b/src/Internal/Config/ErrorStrings.elm index 80b3358..0c3f562 100644 --- a/src/Internal/Config/ErrorStrings.elm +++ b/src/Internal/Config/ErrorStrings.elm @@ -37,4 +37,4 @@ serverSaysForbidden error = unsupportedVersion : String unsupportedVersion = - "UNSUPPORTED HOMESERVER: the homeserver only supports Spec versions that this library doesn't support." + "UNSUPPORTED HOMESERVER: the homeserver only supports spec versions that this library doesn't support." diff --git a/src/Internal/Tools/Exceptions.elm b/src/Internal/Tools/Exceptions.elm index c31185e..c950cfa 100644 --- a/src/Internal/Tools/Exceptions.elm +++ b/src/Internal/Tools/Exceptions.elm @@ -10,12 +10,14 @@ import Internal.Tools.DecodeExtra exposing (opField) import Json.Decode as D import Json.Encode as E + {-| Errors that may return in any circumstance: -- `InternetException` Errors that the `elm/http` library might raise. -- `SDKException` Errors that this SDK might raise if it doesn't like its own input -- `ServerException` Errors that the homeserver might bring -- `UnsupportedSpecVersion` This SDK does not support the needed spec versions for certain operations - usually because a homeserver is extremely old. + - `InternetException` Errors that the `elm/http` library might raise. + - `SDKException` Errors that this SDK might raise if it doesn't like its own input + - `ServerException` Errors that the homeserver might bring + - `UnsupportedSpecVersion` This SDK does not support the needed spec versions for certain operations - usually because a homeserver is extremely old. + -} type Error = InternetException Http.Error @@ -32,12 +34,14 @@ input. - `CouldntGetTimestamp` The Elm core somehow failed to get the current Unix timestamp. - `NotSupportedYet` Some part of the SDK is intended to be implemented - but it isn't yet. + - `NoAccessToken` There is no more access token and no way of getting a new one. -} type ClientError = ServerReturnsBadJSON String | CouldntGetTimestamp | NotSupportedYet String + | NoAccessToken {-| Potential error codes that the server may return. If the error is not a @@ -201,7 +205,7 @@ errorDecoder name code decoder = errorToString : Error -> String errorToString e = case e of - UnsupportedVersion -> + UnsupportedSpecVersion -> ES.unsupportedVersion SDKException (ServerReturnsBadJSON s) -> diff --git a/src/Internal/Tools/Timestamp.elm b/src/Internal/Tools/Timestamp.elm index 983fcff..fd38d2a 100644 --- a/src/Internal/Tools/Timestamp.elm +++ b/src/Internal/Tools/Timestamp.elm @@ -1,7 +1,8 @@ -module Internal.Tools.Timestamp exposing (Timestamp, encodeTimestamp, timestampDecoder) +module Internal.Tools.Timestamp exposing (Timestamp, encodeTimestamp, generateTransactionId, timestampDecoder) import Json.Decode as D import Json.Encode as E +import Task exposing (Task) import Time @@ -21,3 +22,13 @@ encodeTimestamp = timestampDecoder : D.Decoder Timestamp timestampDecoder = D.map Time.millisToPosix D.int + + +{-| Generate a transaction id from the current Unix timestamp +-} +generateTransactionId : Task x String +generateTransactionId = + Time.now + |> Task.map Time.posixToMillis + |> Task.map String.fromInt + |> Task.map ((++) "elm") diff --git a/src/Internal/Tools/VersionControl.elm b/src/Internal/Tools/VersionControl.elm index c80c861..b1e8331 100644 --- a/src/Internal/Tools/VersionControl.elm +++ b/src/Internal/Tools/VersionControl.elm @@ -2,6 +2,7 @@ module Internal.Tools.VersionControl exposing ( VersionControl, withBottomLayer , MiddleLayer, addMiddleLayer , toDict, fromVersion, fromVersionList + , isSupported , mostRecentFromVersionList, sameForVersion ) @@ -62,6 +63,11 @@ you prefer to use. @docs toDict, fromVersion, mostRecentFromVerionList, fromVersionList + +# Checking functions + +@docs isSupported + -} import Dict exposing (Dict) @@ -138,6 +144,17 @@ fromVersionList versionList vc = versionList +{-| Sometimes, you may not wish to "just" get the info. +Sometimes, all you're interested in, is whether a given version is supported. + +In such a case, you can use this function to check whether a given version is supported. + +-} +isSupported : String -> VersionControl a b -> Bool +isSupported version (VersionControl d) = + Dict.member version d.versions + + {-| Get a dict of all available functions. -} toDict : VersionControl a b -> Dict String (a -> b)