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 {
|
||||
bucket?: string | null
|
||||
url: string
|
||||
onComplete: () => Promise<{
|
||||
rateLimited: any
|
||||
bucket?: string | null
|
||||
before: boolean
|
||||
} | undefined>
|
||||
bucket?: string | null
|
||||
url: string
|
||||
}
|
||||
|
||||
export interface RateLimit {
|
||||
|
@ -93,10 +93,8 @@ export class RESTManager {
|
|||
request.bucket
|
||||
)
|
||||
if (rateLimitResetIn !== false) {
|
||||
// This request is still rate limited read to queue
|
||||
this.queue(request)
|
||||
} else {
|
||||
// This request is not rate limited so it should be run
|
||||
const result = await request.onComplete()
|
||||
if (result?.rateLimited !== undefined) {
|
||||
this.queue({
|
||||
|
@ -107,10 +105,8 @@ export class RESTManager {
|
|||
}
|
||||
} else {
|
||||
if (rateLimitedURLResetIn !== false) {
|
||||
// This URL is rate limited readd to queue
|
||||
this.queue(request)
|
||||
} else {
|
||||
// This request has no bucket id so it should be processed
|
||||
const result = await request.onComplete()
|
||||
if (result?.rateLimited !== undefined) {
|
||||
this.queue({
|
||||
|
@ -253,27 +249,35 @@ export class RESTManager {
|
|||
}
|
||||
|
||||
async handleStatusCode(
|
||||
response: Response
|
||||
response: Response, body: any, data: { [key: string]: any }
|
||||
): Promise<undefined> {
|
||||
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()
|
||||
const text = Deno.inspect(body.errors)
|
||||
let text: undefined | string = Deno.inspect(body.errors === undefined ? body : body.errors)
|
||||
if (text === 'undefined') text = undefined
|
||||
|
||||
if (status === HttpResponseCode.Unauthorized)
|
||||
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 ([
|
||||
HttpResponseCode.BadRequest,
|
||||
HttpResponseCode.NotFound,
|
||||
HttpResponseCode.Forbidden,
|
||||
HttpResponseCode.MethodNotAllowed
|
||||
].includes(status)) {
|
||||
throw new Error(`Request - Client Error. Code: ${status}\n${text}`)
|
||||
throw new Error(Deno.inspect(error))
|
||||
} 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')
|
||||
}
|
||||
|
||||
|
@ -319,12 +323,13 @@ export class RESTManager {
|
|||
|
||||
const response = await fetch(urlToUse, requestData)
|
||||
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)
|
||||
|
||||
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 (
|
||||
json.retry_after !== undefined ||
|
||||
json.message === 'You are being rate limited.'
|
||||
|
|
|
@ -11,6 +11,7 @@ client.on('debug', console.log)
|
|||
|
||||
client.on('ready', () => {
|
||||
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}`))
|
||||
|
|
Loading…
Reference in a new issue