feat(REST): Improved Error Handling. Now shows better Errors.
This commit is contained in:
parent
b935bb1238
commit
7ba8978276
3 changed files with 68 additions and 15 deletions
47
src/managers/memberRoles.ts
Normal file
47
src/managers/memberRoles.ts
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import { Client } from '../models/client.ts'
|
||||||
|
import { CHANNEL } from '../types/endpoint.ts'
|
||||||
|
import { BaseChildManager } from './baseChild.ts'
|
||||||
|
import { RolePayload } from "../types/role.ts"
|
||||||
|
import { Role } from "../structures/role.ts"
|
||||||
|
import { Member } from "../structures/member.ts"
|
||||||
|
import { RolesManager } from "./roles.ts"
|
||||||
|
import { MemberPayload } from "../types/guild.ts"
|
||||||
|
|
||||||
|
export class MemberRolesManager extends BaseChildManager<
|
||||||
|
RolePayload,
|
||||||
|
Role
|
||||||
|
> {
|
||||||
|
member: Member
|
||||||
|
|
||||||
|
constructor (client: Client, parent: RolesManager, member: Member) {
|
||||||
|
super(client, parent as any)
|
||||||
|
this.member = member
|
||||||
|
}
|
||||||
|
|
||||||
|
async get (id: string): Promise<Role | undefined> {
|
||||||
|
const res = await this.parent.get(id)
|
||||||
|
const mem = await (this.parent as any).guild.members.get(this.member.id) as MemberPayload
|
||||||
|
if (res !== undefined && mem.roles.includes(res.id) === true) return res
|
||||||
|
else return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete(id: string): Promise<boolean> {
|
||||||
|
return this.client.rest.delete(CHANNEL(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
async array (): Promise<Role[]> {
|
||||||
|
const arr = (await this.parent.array()) as Role[]
|
||||||
|
const mem = await (this.parent as any).guild.members.get(this.member.id) as MemberPayload
|
||||||
|
return arr.filter(
|
||||||
|
(c: any) => mem.roles.includes(c.id)
|
||||||
|
) as any
|
||||||
|
}
|
||||||
|
|
||||||
|
async flush (): Promise<boolean> {
|
||||||
|
const arr = await this.array()
|
||||||
|
for (const elem of arr) {
|
||||||
|
this.parent.delete(elem.id)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,13 +25,13 @@ export interface RequestHeaders {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QueuedItem {
|
export interface QueuedItem {
|
||||||
|
bucket?: string | null
|
||||||
|
url: string
|
||||||
onComplete: () => Promise<{
|
onComplete: () => Promise<{
|
||||||
rateLimited: any
|
rateLimited: any
|
||||||
bucket?: string | null
|
bucket?: string | null
|
||||||
before: boolean
|
before: boolean
|
||||||
} | undefined>
|
} | undefined>
|
||||||
bucket?: string | null
|
|
||||||
url: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RateLimit {
|
export interface RateLimit {
|
||||||
|
@ -93,10 +93,8 @@ export class RESTManager {
|
||||||
request.bucket
|
request.bucket
|
||||||
)
|
)
|
||||||
if (rateLimitResetIn !== false) {
|
if (rateLimitResetIn !== false) {
|
||||||
// This request is still rate limited read to queue
|
|
||||||
this.queue(request)
|
this.queue(request)
|
||||||
} else {
|
} else {
|
||||||
// This request is not rate limited so it should be run
|
|
||||||
const result = await request.onComplete()
|
const result = await request.onComplete()
|
||||||
if (result?.rateLimited !== undefined) {
|
if (result?.rateLimited !== undefined) {
|
||||||
this.queue({
|
this.queue({
|
||||||
|
@ -107,10 +105,8 @@ export class RESTManager {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (rateLimitedURLResetIn !== false) {
|
if (rateLimitedURLResetIn !== false) {
|
||||||
// This URL is rate limited readd to queue
|
|
||||||
this.queue(request)
|
this.queue(request)
|
||||||
} else {
|
} else {
|
||||||
// This request has no bucket id so it should be processed
|
|
||||||
const result = await request.onComplete()
|
const result = await request.onComplete()
|
||||||
if (result?.rateLimited !== undefined) {
|
if (result?.rateLimited !== undefined) {
|
||||||
this.queue({
|
this.queue({
|
||||||
|
@ -253,27 +249,35 @@ export class RESTManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleStatusCode(
|
async handleStatusCode(
|
||||||
response: Response
|
response: Response, body: any, data: { [key: string]: any }
|
||||||
): Promise<undefined> {
|
): Promise<undefined> {
|
||||||
const status = response.status
|
const status = response.status
|
||||||
|
|
||||||
if ((status >= 200 && status < 400) || status === HttpResponseCode.TooManyRequests) return
|
if (
|
||||||
|
(status >= 200 && status < 400)
|
||||||
|
|| status === HttpResponseCode.NoContent
|
||||||
|
|| status === HttpResponseCode.TooManyRequests
|
||||||
|
) return
|
||||||
|
|
||||||
const body = await response.json()
|
let text: undefined | string = Deno.inspect(body.errors === undefined ? body : body.errors)
|
||||||
const text = Deno.inspect(body.errors)
|
if (text === 'undefined') text = undefined
|
||||||
|
|
||||||
if (status === HttpResponseCode.Unauthorized)
|
if (status === HttpResponseCode.Unauthorized)
|
||||||
throw new Error(`Request was not successful (Unauthorized). Invalid Token.\n${text}`)
|
throw new Error(`Request was not successful (Unauthorized). Invalid Token.\n${text}`)
|
||||||
|
|
||||||
|
// At this point we know it is error
|
||||||
|
let error = { url: response.url, status, method: data.method, body: data.body }
|
||||||
|
if (body !== undefined) error = Object.assign(error, body)
|
||||||
|
|
||||||
if ([
|
if ([
|
||||||
HttpResponseCode.BadRequest,
|
HttpResponseCode.BadRequest,
|
||||||
HttpResponseCode.NotFound,
|
HttpResponseCode.NotFound,
|
||||||
HttpResponseCode.Forbidden,
|
HttpResponseCode.Forbidden,
|
||||||
HttpResponseCode.MethodNotAllowed
|
HttpResponseCode.MethodNotAllowed
|
||||||
].includes(status)) {
|
].includes(status)) {
|
||||||
throw new Error(`Request - Client Error. Code: ${status}\n${text}`)
|
throw new Error(Deno.inspect(error))
|
||||||
} else if (status === HttpResponseCode.GatewayUnavailable) {
|
} else if (status === HttpResponseCode.GatewayUnavailable) {
|
||||||
throw new Error(`Request - Server Error. Code: ${status}\n${text}`)
|
throw new Error(Deno.inspect(error))
|
||||||
} else throw new Error('Request - Unknown Error')
|
} else throw new Error('Request - Unknown Error')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,12 +323,13 @@ export class RESTManager {
|
||||||
|
|
||||||
const response = await fetch(urlToUse, requestData)
|
const response = await fetch(urlToUse, requestData)
|
||||||
const bucketFromHeaders = this.processHeaders(url, response.headers)
|
const bucketFromHeaders = this.processHeaders(url, response.headers)
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
||||||
this.handleStatusCode(response)
|
|
||||||
|
|
||||||
if (response.status === 204) return resolve(undefined)
|
if (response.status === 204) return resolve(undefined)
|
||||||
|
|
||||||
const json = await response.json()
|
const json: any = await response.json()
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
|
this.handleStatusCode(response, json, requestData)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
json.retry_after !== undefined ||
|
json.retry_after !== undefined ||
|
||||||
json.message === 'You are being rate limited.'
|
json.message === 'You are being rate limited.'
|
||||||
|
|
|
@ -11,6 +11,7 @@ client.on('debug', console.log)
|
||||||
|
|
||||||
client.on('ready', () => {
|
client.on('ready', () => {
|
||||||
console.log(`[Login] Logged in as ${client.user?.tag}!`)
|
console.log(`[Login] Logged in as ${client.user?.tag}!`)
|
||||||
|
client.rest.get('https://discord.com/api/v8/users/123')
|
||||||
})
|
})
|
||||||
|
|
||||||
client.on('messageCreate', msg => console.log(`${msg.author.tag}: ${msg.content}`))
|
client.on('messageCreate', msg => console.log(`${msg.author.tag}: ${msg.content}`))
|
||||||
|
|
Loading…
Reference in a new issue