Client Configurations + Auto-Retry on HTTP Request Failure #31
@ -8,31 +8,33 @@ local tokens = {
|
||||
local Utils = require(script.Parent.Utils)
|
||||
local MarcSyncClient = {}
|
||||
|
||||
local Types = require(script.Parent.Types)
|
||||
|
||||
MarcSyncClient.getVersion = function(self:typeof(MarcSyncClient), clientId: number?):string
|
||||
self:_checkInstallation()
|
||||
local url = ""
|
||||
if clientId then url = "/"..clientId end
|
||||
local result = Utils.makeHTTPRequest("GET", "https://api.marcsync.dev/v0/utils/version"..url);
|
||||
local result = Utils.makeHTTPRequest("", "GET", "https://api.marcsync.dev/v0/utils/version"..url, nil, nil, self._options);
|
||||
return result["version"]
|
||||
end
|
||||
|
||||
MarcSyncClient.createCollection = function(self:typeof(MarcSyncClient), collectionName: string):typeof(require(script.Parent.Objects.Collection).new())
|
||||
if not self._accessToken then error("[MarcSync] Please set a Token before using MarcSync.") end
|
||||
if not collectionName then error("No CollectionName Provided") end
|
||||
local result = Utils.makeHTTPRequest("collection", "POST", "https://api.marcsync.dev/v0/collection/"..collectionName, {}, self._accessToken);
|
||||
local result = Utils.makeHTTPRequest("collection", "POST", "https://api.marcsync.dev/v0/collection/"..collectionName, {}, self._accessToken, self._options);
|
||||
|
||||
if not result["success"] then error(result["errorMessage"]) end
|
||||
result = require(script.Parent.Objects.Collection).new(collectionName, self._accessToken)
|
||||
result = require(script.Parent.Objects.Collection).new(collectionName, self._accessToken, self._options)
|
||||
|
||||
return result
|
||||
end
|
||||
MarcSyncClient.fetchCollection = function(self:typeof(MarcSyncClient), collectionName: string):typeof(require(script.Parent.Objects.Collection).new())
|
||||
self:_checkInstallation()
|
||||
if not collectionName then error("No CollectionName Provided") end
|
||||
local result = Utils.makeHTTPRequest("collection", "GET", "https://api.marcsync.dev/v0/collection/"..collectionName, {}, self._accessToken);
|
||||
local result = Utils.makeHTTPRequest("collection", "GET", "https://api.marcsync.dev/v0/collection/"..collectionName, {}, self._accessToken, self._options);
|
||||
|
||||
if not result["success"] then error(result["errorMessage"]) end
|
||||
result = require(script.Parent.Objects.Collection).new(collectionName, self._accessToken)
|
||||
result = require(script.Parent.Objects.Collection).new(collectionName, self._accessToken, self._options)
|
||||
|
||||
return result
|
||||
end
|
||||
@ -40,15 +42,16 @@ MarcSyncClient.getCollection = function(self:typeof(MarcSyncClient), collectionN
|
||||
if typeof(self) ~= "table" then error("Please use : instead of .") end
|
||||
self:_checkInstallation()
|
||||
if not collectionName then error("No CollectionName Provided") end
|
||||
return require(script.Parent.Objects.Collection).new(collectionName, self._accessToken)
|
||||
return require(script.Parent.Objects.Collection).new(collectionName, self._accessToken, self._options)
|
||||
end
|
||||
|
||||
return {
|
||||
new = function(accessToken: string):typeof(MarcSyncClient)
|
||||
new = function(accessToken: string, options: Types.ClientOptions?):typeof(MarcSyncClient)
|
||||
if not accessToken then warn("Token not provided while creating a new MarcSync Object.") end
|
||||
if not tokens[accessToken] then warn("Token provided for creating a new MarcSync Object not Found in Token Table, using it as token instead.") else accessToken = tokens[accessToken] end
|
||||
local self = {}
|
||||
self._accessToken = accessToken
|
||||
self._options = options or {retryCount = 3}
|
||||
self._checkInstallation = function()
|
||||
if not self then error("Please Setup MarcSync before using MarcSync.") end
|
||||
if not self._accessToken then error("[MarcSync] Please set a Token before using MarcSync.") end
|
@ -7,11 +7,11 @@ local Collection = {}
|
||||
|
||||
Collection.createEntry = function(self:typeof(Collection), data:Types.EntryData):typeof(Entry.new())
|
||||
if not self._collectionName then error("[MarcSync: Collection] Invalid Object created or trying to access an destroied object.") end
|
||||
local result = Utils.makeHTTPRequest("entry", "POST", "https://api.marcsync.dev/v0/entries/"..self._collectionName, {["data"]=data}, self._accessToken);
|
||||
local result = Utils.makeHTTPRequest("entry", "POST", "https://api.marcsync.dev/v0/entries/"..self._collectionName, {["data"]=data}, self._accessToken, self._options);
|
||||
|
||||
if result["success"] and result["objectId"] then
|
||||
data["_id"] = result["objectId"]
|
||||
result = require(script.Parent.Entry).new(self._collectionName, data, self._accessToken)
|
||||
result = require(script.Parent.Entry).new(self._collectionName, data, self._accessToken, self._options)
|
||||
else
|
||||
error(result["errorMessage"])
|
||||
end
|
||||
@ -21,7 +21,7 @@ end
|
||||
|
||||
Collection.updateEntries = function(self:typeof(Collection), filters:Types.EntryData, data:Types.EntryData):number
|
||||
if not self._collectionName then error("[MarcSync: Collection] Invalid Object created or trying to access an destroied object.") end
|
||||
local result = Utils.makeHTTPRequest("entry", "PUT", "https://api.marcsync.dev/v0/entries/"..self._collectionName, {["filters"]=filters,["data"]=data}, self._accessToken);
|
||||
local result = Utils.makeHTTPRequest("entry", "PUT", "https://api.marcsync.dev/v0/entries/"..self._collectionName, {["filters"]=filters,["data"]=data}, self._accessToken, self._options);
|
||||
if not result["success"] then error(result["errorMessage"]) end
|
||||
|
||||
return result["modifiedEntries"]
|
||||
@ -30,11 +30,11 @@ end
|
||||
Collection.getEntries = function(self:typeof(Collection), filters:Types.EntryData):{[number]:typeof(Entry.new())}
|
||||
if not self._collectionName then error("[MarcSync: Collection] Invalid Object created or trying to access an destroied object.") end
|
||||
if not filters then filters = {} end
|
||||
local result = Utils.makeHTTPRequest("entry", "DELETE", "https://api.marcsync.dev/v0/entries/"..self._collectionName.."?isQuery=true", {["filters"]=filters}, self._accessToken);
|
||||
local result = Utils.makeHTTPRequest("entry", "DELETE", "https://api.marcsync.dev/v0/entries/"..self._collectionName.."?isQuery=true", {["filters"]=filters}, self._accessToken, self._options);
|
||||
if result["success"] and result["entries"] then
|
||||
local _result = {}
|
||||
for index,entry in pairs(result["entries"]) do
|
||||
_result[index] = require(script.Parent.Entry).new(self._collectionName, entry, self._accessToken)
|
||||
_result[index] = require(script.Parent.Entry).new(self._collectionName, entry, self._accessToken, self._options)
|
||||
end
|
||||
result = _result
|
||||
else
|
||||
@ -46,7 +46,7 @@ end
|
||||
|
||||
Collection.deleteEntries = function(self:typeof(Collection), filters:Types.EntryData):number
|
||||
if not self._collectionName then error("[MarcSync: Collection] Invalid Object created or trying to access an destroied object.") end
|
||||
local result = Utils.makeHTTPRequest("DELETE", "https://api.marcsync.dev/v0/entries/"..self._collectionName, {["filters"]=filters}, self._accessToken);
|
||||
local result = Utils.makeHTTPRequest("DELETE", "https://api.marcsync.dev/v0/entries/"..self._collectionName, {["filters"]=filters}, self._accessToken, self._options);
|
||||
if not result["success"] then error(result["errorMessage"]) end
|
||||
|
||||
return result["deletedEntries"]
|
||||
@ -54,16 +54,17 @@ end
|
||||
|
||||
Collection.drop = function(self:typeof(Collection))
|
||||
if not self._collectionName then error("[MarcSync: Collection] Invalid Object created or trying to access an destroied object.") end
|
||||
local result = Utils.makeHTTPRequest("collection", "DELETE", "https://api.marcsync.dev/v0/collection/"..self._collectionName, {}, self._accessToken);
|
||||
local result = Utils.makeHTTPRequest("collection", "DELETE", "https://api.marcsync.dev/v0/collection/"..self._collectionName, {}, self._accessToken, self._options);
|
||||
if not result["success"] then error(result["errorMessage"]) end
|
||||
self = nil
|
||||
end
|
||||
|
||||
return {
|
||||
new = function(collectionName: string, accessToken: string):typeof(Collection)
|
||||
new = function(collectionName: string, accessToken: string, options: Types.ClientOptions):typeof(Collection)
|
||||
local self = {}
|
||||
self._collectionName = collectionName
|
||||
self._accessToken = accessToken
|
||||
self._options = options
|
||||
|
||||
self = setmetatable(self, {
|
||||
__index = Collection
|
||||
|
@ -14,7 +14,7 @@ Entry.getValues = function(self:typeof(Entry)):Types.EntryData
|
||||
end
|
||||
|
||||
Entry.updateValues = function(self:typeof(Entry), data:Types.EntryData):number
|
||||
local result = Utils.makeHTTPRequest("entry", "PUT", "https://api.marcsync.dev/v0/entries/"..self._tableId, {["filters"]={["_id"]=self._objectId},["data"]=data}, self._accessToken);
|
||||
local result = Utils.makeHTTPRequest("entry", "PUT", "https://api.marcsync.dev/v0/entries/"..self._tableId, {["filters"]={["_id"]=self._objectId},["data"]=data}, self._accessToken, self._options);
|
||||
|
||||
if result["success"] and result["modifiedEntries"] and result["modifiedEntries"] > 0 then
|
||||
for i,v in pairs(data) do
|
||||
@ -29,7 +29,7 @@ end
|
||||
|
||||
Entry.delete = function(self:typeof(Entry))
|
||||
if typeof(self) ~= "table" then error("Please use : instead of .") end
|
||||
local result = Utils.makeHTTPRequest("entry", "DELETE", "https://api.marcsync.dev/v0/entries/"..self._tableId, {["filters"]={["_id"]=self._objectId}}, self._accessToken);
|
||||
local result = Utils.makeHTTPRequest("entry", "DELETE", "https://api.marcsync.dev/v0/entries/"..self._tableId, {["filters"]={["_id"]=self._objectId}}, self._accessToken, self._options);
|
||||
|
||||
if not result["success"] then error(result["errorMessage"]) end
|
||||
self = nil
|
||||
@ -37,13 +37,14 @@ Entry.delete = function(self:typeof(Entry))
|
||||
end
|
||||
|
||||
return {
|
||||
new = function(tableId:string, entryData:Types.EntryData, accessToken:string):typeof(Entry)
|
||||
new = function(tableId:string, entryData:Types.EntryData, accessToken:string, options: Types.ClientOptions):typeof(Entry)
|
||||
if not tableId or not entryData or not entryData["_id"] or not accessToken then error("[MarcSync: Entry] Tried creating invalid Entry Object.") end
|
||||
local self = {}
|
||||
self._tableId = tableId
|
||||
self._entryData = entryData
|
||||
self._objectId = entryData["_id"]
|
||||
self._accessToken = accessToken
|
||||
self._options = options
|
||||
|
||||
self = setmetatable(self, {
|
||||
__index = Entry
|
||||
|
@ -4,4 +4,8 @@ export type EntryData = {
|
||||
[string]: any
|
||||
}
|
||||
|
||||
export type ClientOptions = {
|
||||
retryCount: number
|
||||
}
|
||||
|
||||
return types
|
@ -3,8 +3,9 @@ local CollectionError = require(script.Parent.Errors.Collection)
|
||||
local EntryError = require(script.Parent.Errors.Entry)
|
||||
|
||||
local HttpService = game:GetService("HttpService")
|
||||
local Types = require(script.Parent.Types)
|
||||
|
||||
function errorHandler(type: string, resultBody: any, resultObject: {})
|
||||
function errorHandler(callInformation: {}, resultBody: any, resultObject: {}, retryCount: number)
|
||||
local Error;
|
||||
if typeof(resultBody) == typeof({}) and resultBody["message"] then
|
||||
Error = resultBody["message"]
|
||||
@ -14,30 +15,39 @@ function errorHandler(type: string, resultBody: any, resultObject: {})
|
||||
Error = "An Unexpected Error occoured."
|
||||
end
|
||||
|
||||
if type == "collection" then
|
||||
if resultObject["StatusCode"] == 401 then
|
||||
local statusCode = resultObject["StatusCode"]
|
||||
if callInformation.type == "collection" then
|
||||
if statusCode == 401 then
|
||||
Error = AuthorizationError.InvalidAccessToken("InvalidAccessToken")
|
||||
elseif resultObject["StatusCode"] == 404 then
|
||||
elseif statusCode == 404 then
|
||||
Error = CollectionError.CollectionNotFound("CollectionNotFound")
|
||||
elseif resultObject["StatusCode"] == 400 then
|
||||
elseif statusCode == 400 then
|
||||
Error = CollectionError.CollectionAlreadyExists("CollectionAlreadyExists")
|
||||
end
|
||||
elseif type == "entry" then
|
||||
if resultObject["StatusCode"] == 401 then
|
||||
elseif callInformation.type == "entry" then
|
||||
if statusCode == 401 then
|
||||
Error = AuthorizationError.InvalidAccessToken("InvalidAccessToken")
|
||||
elseif resultObject["StatusCode"] == 404 then
|
||||
elseif statusCode == 404 then
|
||||
Error = CollectionError.CollectionNotFound("CollectionNotFound")
|
||||
elseif resultObject["StatusCode"] == 400 then
|
||||
elseif statusCode == 400 then
|
||||
Error = EntryError.InvalidEntryData("InvalidEntryData")
|
||||
end
|
||||
end
|
||||
|
||||
if(statusCode ~= 400 and statusCode ~= 401) then
|
||||
if retryCount > 0 then
|
||||
warn("[MarcSync HTTPRequest Handler] MarcSync HTTP Request failed with error: "..Error.." and status code: "..statusCode..". Retrying Request. ("..retryCount..") retries left")
|
||||
task.wait(3)
|
||||
return require(script.Parent.Utils).makeHTTPRequest(callInformation.type, callInformation.method, callInformation.url, callInformation.body, callInformation.authorization, {retryCount = retryCount - 1})
|
||||
end
|
||||
end
|
||||
|
||||
return {["success"] = false, ["errorMessage"] = Error}
|
||||
end
|
||||
|
||||
local utils = {}
|
||||
|
||||
function utils.makeHTTPRequest(type: string, method: string, url: string, body: {}, authorization: string):{["success"]: boolean, ["message"]: string}
|
||||
function utils.makeHTTPRequest(type: string, method: string, url: string, body: {}, authorization: string, options: Types.ClientOptions):{["success"]: boolean, ["message"]: string}
|
||||
local resultObj;
|
||||
local resultBody;
|
||||
local success = pcall(function()
|
||||
@ -54,7 +64,13 @@ function utils.makeHTTPRequest(type: string, method: string, url: string, body:
|
||||
if resultBody["warning"] then warn('[MarcSync HTTPRequest Handler] MarcSync HTTP Request returned warning for URL "'..url..'" with body: "'..HttpService:JSONEncode(body)..'": '..resultBody["warning"]) end
|
||||
return resultBody
|
||||
end
|
||||
return errorHandler(type, resultBody, resultObj)
|
||||
return errorHandler({
|
||||
type = type,
|
||||
method = method,
|
||||
url = url,
|
||||
body = body,
|
||||
authorization = authorization
|
||||
}, resultBody, resultObj, options.retryCount)
|
||||
end
|
||||
|
||||
return utils
|
@ -18,6 +18,24 @@ METHODS
|
||||
|
||||
</div>
|
||||
|
||||
## CONSTRUCTOR
|
||||
|
||||
### .new(`accessToken:` [string](https://www.lua.org/pil/2.4.html), `options:` [ClientOptions?](../types/ClientOptions))
|
||||
Creates a new MarcSync client.
|
||||
|
||||
:::info Info
|
||||
When creating a new client, you must provide an `accessToken`. This argument can either be the key of the "tokens" table in the client's Class or the actual token itself. If you provide the key, the client will automatically try to fetch the token from the "tokens" table. If you provide the token itself, the client will use that token instead. If no token is found by the key provided, it will use the key as the token itself.
|
||||
:::
|
||||
|
||||
:::info Info
|
||||
The `options` argument is optional and can be used to specify the options of the client. If you do not provide any options, the client will use the default options. The default options are as follows:
|
||||
```lua
|
||||
{
|
||||
retryCount = 3
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## METHODS
|
||||
|
||||
### :getVersion(`clientId:` [number?](https://www.lua.org/pil/2.3.html))
|
||||
|
11
website/docs-marcsync-dev/docs/types/ClientOptions.md
Normal file
11
website/docs-marcsync-dev/docs/types/ClientOptions.md
Normal file
@ -0,0 +1,11 @@
|
||||
# ClientOptions
|
||||
|
||||
ClientOptions is a type which is used to specify the options of a client. It is used in the [MarcSyncClient](../classes/MarcSyncClient) class when creating a new client.
|
||||
|
||||
## Type Definition
|
||||
|
||||
```typescript
|
||||
type ClientOptions = {
|
||||
retryCount: number
|
||||
}
|
||||
```
|
Loading…
x
Reference in New Issue
Block a user