refactor(rest): separate functions into diff files (#685)

* shtufffff

* fixe rate limit path infinite loop

* refactor

* ID > id

* Update process_request_headers.ts

* file names

Co-authored-by: ITOH <72305210+itohatweb@users.noreply.github.com>
Co-authored-by: ayntee <ayyantee@gmail.com>
This commit is contained in:
Skillz4Killz
2021-03-29 15:50:08 -04:00
committed by GitHub
parent 79d57f0377
commit ebb15afa0e
16 changed files with 444 additions and 708 deletions
+135
View File
@@ -0,0 +1,135 @@
import { rest } from "./rest.ts";
export function runMethod(
method: RequestMethods,
url: string,
body?: unknown,
retryCount = 0,
bucketId?: string | null,
) {
rest.eventHandlers.debug?.(
{
type: "requestCreate",
data: { method, url, body, retryCount, bucketId },
},
);
const errorStack = new Error("Location:");
Error.captureStackTrace(errorStack);
// For proxies we don't need to do any of the legwork so we just forward the request
if (
!url.startsWith(`${BASE_URL}/v${API_VERSION}`) &&
!url.startsWith(IMAGE_BASE_URL)
) {
return fetch(url, {
body: JSON.stringify(body || {}),
headers: {
authorization: rest.authorization,
},
method: method.toUpperCase(),
})
.then((res) => {
if (res.status === 204) return undefined;
return res.json();
})
.catch((error) => {
console.error(error);
throw errorStack;
});
}
// No proxy so we need to handle all rate limiting and such
// deno-lint-ignore no-async-promise-executor
return new Promise(async (resolve, reject) => {
const callback = async () => {
try {
const rateLimitResetIn = await rest.checkRatelimits(url);
if (rateLimitResetIn) {
return { rateLimited: rateLimitResetIn, beforeFetch: true, bucketId };
}
const query = method === "get" && body
? // deno-lint-ignore no-explicit-any
Object.entries(body as any).map(([key, value]) =>
// deno-lint-ignore no-explicit-any
`${encodeURIComponent(key)}=${encodeURIComponent(value as any)}`
)
.join("&")
: "";
const urlToUse = method === "get" && query ? `${url}?${query}` : url;
rest.eventHandlers.debug?.(
{
type: "requestFetch",
data: { method, url, body, retryCount, bucketId },
},
);
const response = await fetch(
urlToUse,
rest.createRequestBody(body, method),
);
rest.eventHandlers.debug?.(
{
type: "requestFetched",
data: { method, url, body, retryCount, bucketId, response },
},
);
const bucketIdFromHeaders = rest.processHeaders(url, response.headers);
await rest.handleStatusCode(response, errorStack);
// Sometimes Discord returns an empty 204 response that can't be made to JSON.
if (response.status === 204) return resolve(undefined);
const json = await response.json();
if (
json.retry_after ||
json.message === "You are being rate limited."
) {
if (retryCount > 10) {
rest.eventHandlers.debug?.(
{
type: "error",
data: { method, url, body, retryCount, bucketId, errorStack },
},
);
throw new Error(Errors.RATE_LIMIT_RETRY_MAXED);
}
return {
rateLimited: json.retry_after,
beforeFetch: false,
bucketId: bucketIdFromHeaders,
};
}
rest.eventHandlers.debug?.(
{
type: "requestSuccess",
data: { method, url, body, retryCount, bucketId },
},
);
return resolve(json);
} catch (error) {
rest.eventHandlers.debug?.(
{
type: "error",
data: { method, url, body, retryCount, bucketId, errorStack },
},
);
return reject(error);
}
};
rest.addToQueue({
callback,
bucketId,
url,
});
if (!rest.queueInProcess) {
rest.queueInProcess = true;
await rest.processQueue();
}
});
}