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…
	
	Add table
		Add a link
		
	
		Reference in a new issue