seyfert 4.2.1 → 4.2.2-dev-22071590650.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +13 -0
  2. package/lib/api/api.d.ts +4 -2
  3. package/lib/api/api.js +57 -11
  4. package/lib/builders/Attachment.d.ts +1 -1
  5. package/lib/builders/Attachment.js +40 -6
  6. package/lib/builders/Button.js +6 -1
  7. package/lib/builders/CheckboxGroup.d.ts +1 -1
  8. package/lib/builders/CheckboxGroup.js +9 -1
  9. package/lib/builders/Label.js +9 -1
  10. package/lib/builders/Poll.js +6 -1
  11. package/lib/builders/RadioGroup.d.ts +1 -1
  12. package/lib/builders/RadioGroup.js +9 -1
  13. package/lib/builders/Section.d.ts +1 -1
  14. package/lib/builders/Section.js +9 -1
  15. package/lib/builders/SelectMenu.d.ts +1 -1
  16. package/lib/builders/SelectMenu.js +7 -1
  17. package/lib/cache/adapters/workeradapter.js +1 -1
  18. package/lib/cache/index.js +144 -42
  19. package/lib/client/base.js +4 -2
  20. package/lib/client/workerclient.js +4 -2
  21. package/lib/commands/applications/chat.js +1 -1
  22. package/lib/commands/handler.js +3 -1
  23. package/lib/commands/optionresolver.d.ts +1 -1
  24. package/lib/commands/optionresolver.js +3 -2
  25. package/lib/common/index.d.ts +1 -0
  26. package/lib/common/index.js +1 -0
  27. package/lib/common/it/error.d.ts +115 -0
  28. package/lib/common/it/error.js +138 -0
  29. package/lib/common/it/utils.js +5 -3
  30. package/lib/common/shorters/reactions.js +5 -4
  31. package/lib/components/handler.js +3 -1
  32. package/lib/events/handler.js +3 -1
  33. package/lib/langs/handler.js +3 -1
  34. package/lib/langs/router.js +3 -2
  35. package/lib/structures/Interaction.js +32 -12
  36. package/lib/structures/Poll.js +1 -1
  37. package/lib/websocket/discord/sharder.js +3 -1
  38. package/lib/websocket/discord/socket/custom.js +4 -1
  39. package/lib/websocket/discord/workermanager.js +35 -11
  40. package/package.json +1 -1
package/README.md CHANGED
@@ -49,6 +49,19 @@ npm i seyfert
49
49
  ## Contributing
50
50
  We are open to contributions, fork the repo and make your changes!
51
51
 
52
+ ## Typed errors
53
+
54
+ Seyfert throws `SeyfertError` in validation/runtime checks and can include:
55
+
56
+ - `code`: machine-readable identifier (`INVALID_EMOJI`, `INVALID_OPTIONS_LENGTH`, `MISSING_COMPONENT`, etc.)
57
+ - `metadata`: structured context for diagnostics
58
+
59
+ For validation errors, metadata follows this convention:
60
+
61
+ - `expected`: expected value/shape
62
+ - `received`: value actually received
63
+ - `receivedType`: optional primitive/runtime type
64
+
52
65
  ## Useful links
53
66
 
54
67
  - [GitHub Repository](https://github.com/tiramisulabs/seyfert)
package/lib/api/api.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type UUID } from 'node:crypto';
2
- import { type Awaitable, Logger } from '../common';
2
+ import { type Awaitable, Logger, SeyfertError } from '../common';
3
3
  import type { WorkerSendApiRequest } from '../websocket/discord/worker';
4
4
  import { Bucket } from './bucket';
5
5
  import type { APIRoutes } from './Routes';
@@ -27,7 +27,9 @@ export declare class ApiHandler {
27
27
  protected sendMessage(_body: WorkerSendApiRequest): void;
28
28
  protected postMessage<T = unknown>(body: WorkerSendApiRequest): Promise<T>;
29
29
  request<T = unknown>(method: HttpMethods, url: `/${string}`, { auth, ...request }?: ApiRequestOptions): Promise<T>;
30
- parseError(method: HttpMethods, route: `/${string}`, response: Response, result: string | Record<string, any>): Error;
30
+ parseError(method: HttpMethods, route: `/${string}`, response: Response, result: string | Record<string, any>, originTrace?: {
31
+ stack?: string;
32
+ }): SeyfertError;
31
33
  parseValidationError(data: Record<string, any>, path?: string, errors?: string[]): string[];
32
34
  handle50X(method: HttpMethods, url: `/${string}`, request: ApiRequestOptions, next: () => void): Promise<unknown>;
33
35
  handle429(route: string, method: HttpMethods, url: `/${string}`, request: ApiRequestOptions, response: Response, result: string, next: () => void, reject: (err: unknown) => void, now: number): Promise<unknown>;
package/lib/api/api.js CHANGED
@@ -28,7 +28,9 @@ class ApiHandler {
28
28
  this.debug = true;
29
29
  const worker_threads = (0, common_1.lazyLoadPackage)('node:worker_threads');
30
30
  if (options.workerProxy && !worker_threads?.parentPort && !process.send)
31
- throw new Error('Cannot use workerProxy without a parent.');
31
+ throw new common_1.SeyfertError('API_WORKER_PROXY_PARENT_REQUIRED', {
32
+ metadata: { detail: 'Cannot use workerProxy without a parent.' },
33
+ });
32
34
  if (options.workerProxy)
33
35
  this.workerPromises = new Map();
34
36
  if (worker_threads?.parentPort) {
@@ -79,7 +81,7 @@ class ApiHandler {
79
81
  return uuid;
80
82
  }
81
83
  sendMessage(_body) {
82
- throw new Error('Function not implemented');
84
+ throw new common_1.SeyfertError('FUNCTION_NOT_IMPLEMENTED', { metadata: { detail: 'Function not implemented' } });
83
85
  }
84
86
  postMessage(body) {
85
87
  this.sendMessage(body);
@@ -88,6 +90,8 @@ class ApiHandler {
88
90
  });
89
91
  }
90
92
  async request(method, url, { auth = true, ...request } = {}) {
93
+ const originTrace = {};
94
+ Error.captureStackTrace(originTrace, this.request);
91
95
  if (this.options.workerProxy) {
92
96
  const nonce = this.randomUUID();
93
97
  return this.postMessage({
@@ -151,14 +155,14 @@ class ApiHandler {
151
155
  result = JSON.parse(result);
152
156
  }
153
157
  catch (err) {
154
- this.debugger?.warn('Error parsing result error (', result, ')', err);
158
+ this.debugger?.warn('SeyfertError parsing result error (', result, ')', err);
155
159
  reject(err);
156
160
  return;
157
161
  }
158
162
  }
159
163
  }
160
- const parsedError = this.parseError(method, route, response, result);
161
- this.debugger?.warn(parsedError);
164
+ const parsedError = this.parseError(method, route, response, result, originTrace);
165
+ this.debugger?.warn(parsedError.message);
162
166
  reject(parsedError);
163
167
  return;
164
168
  }
@@ -168,7 +172,7 @@ class ApiHandler {
168
172
  result = JSON.parse(result);
169
173
  }
170
174
  catch (err) {
171
- this.debugger?.warn('Error parsing result (', result, ')', err);
175
+ this.debugger?.warn('Failed parsing result (', result, ')', err);
172
176
  next();
173
177
  reject(err);
174
178
  return;
@@ -195,9 +199,20 @@ class ApiHandler {
195
199
  }
196
200
  });
197
201
  }
198
- parseError(method, route, response, result) {
202
+ parseError(method, route, response, result, originTrace) {
199
203
  let errMessage = '';
204
+ let code;
205
+ const metadata = {
206
+ method,
207
+ route,
208
+ status: response.status,
209
+ statusText: response.statusText,
210
+ };
200
211
  if (typeof result === 'object') {
212
+ if (typeof result.code !== 'undefined') {
213
+ code = String(result.code);
214
+ }
215
+ metadata.response = result;
201
216
  errMessage += `${result.message ?? 'Unknown'} ${result.code ?? ''}\n[${response.status} ${response.statusText}] ${method} ${route}`;
202
217
  if ('errors' in result) {
203
218
  const errors = this.parseValidationError(result.errors);
@@ -207,7 +222,25 @@ class ApiHandler {
207
222
  else {
208
223
  errMessage = `[${response.status} ${response.statusText}] ${method} ${route}`;
209
224
  }
210
- return new Error(errMessage);
225
+ const error = new common_1.SeyfertError(`API_${response.statusText}_${code}`, {
226
+ metadata: {
227
+ ...metadata,
228
+ detail: errMessage,
229
+ },
230
+ });
231
+ const originStack = originTrace?.stack;
232
+ if (originStack) {
233
+ const originLines = originStack
234
+ .split('\n')
235
+ .slice(1)
236
+ .filter(line => !line.includes('node:internal') &&
237
+ !line.includes('/src/api/api.ts') &&
238
+ !line.includes('\\src\\api\\api.ts'));
239
+ if (originLines.length) {
240
+ error.stack = `${error.name}: ${error.message}\n${originLines.join('\n')}`;
241
+ }
242
+ }
243
+ return error;
211
244
  }
212
245
  parseValidationError(data, path = '', errors = []) {
213
246
  for (const key in data) {
@@ -237,7 +270,7 @@ class ApiHandler {
237
270
  }
238
271
  async handle429(route, method, url, request, response, result, next, reject, now) {
239
272
  await this.onRatelimit?.(response, request);
240
- const content = `${JSON.stringify(request)} `;
273
+ const bucket = this.ratelimits.get(route);
241
274
  let retryAfter;
242
275
  const data = JSON.parse(result);
243
276
  if (data.retry_after)
@@ -247,10 +280,23 @@ class ApiHandler {
247
280
  if (Number.isNaN(retryAfter)) {
248
281
  this.debugger?.warn(`${route} Could not extract retry_after from 429 response. ${result}`);
249
282
  next();
250
- reject(new Error('Could not extract retry_after from 429 response.'));
283
+ reject(new common_1.SeyfertError('INVALID_RETRY_AFTER', {
284
+ metadata: {
285
+ ...{
286
+ route,
287
+ method,
288
+ status: response.status,
289
+ result,
290
+ },
291
+ detail: 'Could not extract retry_after from 429 response.',
292
+ },
293
+ }));
251
294
  return false;
252
295
  }
253
- this.debugger?.info(`${response.headers.get('x-ratelimit-global') ? 'Global' : 'Unexpected'} 429: ${result.slice(0, 256)}\n${content} ${now} ${route} ${response.status}: ${this.ratelimits.get(route).remaining}/${this.ratelimits.get(route).limit} left | Reset ${retryAfter} (${this.ratelimits.get(route).reset - now}ms left) | Scope ${response.headers.get('x-ratelimit-scope')}`);
296
+ if (this.debugger) {
297
+ const content = `${JSON.stringify(request)} `;
298
+ this.debugger.info(`${response.headers.get('x-ratelimit-global') ? 'Global' : 'Unexpected'} 429: ${result.slice(0, 256)}\n${content} ${now} ${route} ${response.status}: ${bucket.remaining}/${bucket.limit} left | Reset ${retryAfter} (${bucket.reset - now}ms left) | Scope ${response.headers.get('x-ratelimit-scope')}`);
299
+ }
254
300
  if (retryAfter) {
255
301
  await (0, common_1.delay)(retryAfter);
256
302
  next();
@@ -1,5 +1,5 @@
1
1
  import type { RawFile, UsingClient } from '..';
2
- import type { ImageResolvable, ObjectToLower } from '../common';
2
+ import { type ImageResolvable, type ObjectToLower } from '../common';
3
3
  import { Base } from '../structures/extra/Base';
4
4
  import type { APIAttachment, RESTAPIAttachment } from '../types';
5
5
  export interface AttachmentResolvableMap {
@@ -13,6 +13,7 @@ const node_crypto_1 = require("node:crypto");
13
13
  const node_fs_1 = require("node:fs");
14
14
  const node_path_1 = __importDefault(require("node:path"));
15
15
  const utils_1 = require("../api/utils/utils");
16
+ const common_1 = require("../common");
16
17
  const Base_1 = require("../structures/extra/Base");
17
18
  class Attachment extends Base_1.Base {
18
19
  data;
@@ -159,13 +160,23 @@ async function resolveFiles(resources) {
159
160
  async function resolveAttachmentData(data, type) {
160
161
  if (data instanceof AttachmentBuilder) {
161
162
  if (!data.data.resolvable)
162
- throw new Error('The attachment type has been expressed as attachment but cannot be resolved as one.');
163
+ throw new common_1.SeyfertError('INVALID_ATTACHMENT_TYPE', {
164
+ metadata: {
165
+ ...(0, common_1.createValidationMetadata)('AttachmentBuilder with resolvable data', data.data.resolvable),
166
+ detail: 'The attachment type has been expressed as attachment but cannot be resolved as one.',
167
+ },
168
+ });
163
169
  return { data: data.data.resolvable };
164
170
  }
165
171
  switch (type) {
166
172
  case 'url': {
167
173
  if (!/^https?:\/\//.test(data))
168
- throw new Error(`The attachment type has been expressed as ${type.toUpperCase()} but cannot be resolved as one.`);
174
+ throw new common_1.SeyfertError('INVALID_ATTACHMENT_TYPE', {
175
+ metadata: {
176
+ ...(0, common_1.createValidationMetadata)('string URL starting with http:// or https://', data),
177
+ detail: `The attachment type has been expressed as ${type.toUpperCase()} but cannot be resolved as one.`,
178
+ },
179
+ });
169
180
  const res = await fetch(data);
170
181
  return {
171
182
  data: Buffer.from(await res.arrayBuffer()),
@@ -176,7 +187,12 @@ async function resolveAttachmentData(data, type) {
176
187
  const file = node_path_1.default.resolve(data);
177
188
  const stats = await node_fs_1.promises.stat(file);
178
189
  if (!stats.isFile())
179
- throw new Error(`The attachment type has been expressed as ${type.toUpperCase()} but cannot be resolved as one.`);
190
+ throw new common_1.SeyfertError('INVALID_ATTACHMENT_TYPE', {
191
+ metadata: {
192
+ ...(0, common_1.createValidationMetadata)('path to an existing file', file),
193
+ detail: `The attachment type has been expressed as ${type.toUpperCase()} but cannot be resolved as one.`,
194
+ },
195
+ });
180
196
  return { data: await node_fs_1.promises.readFile(file) };
181
197
  }
182
198
  case 'buffer': {
@@ -188,10 +204,20 @@ async function resolveAttachmentData(data, type) {
188
204
  buffers.push(Buffer.from(resource));
189
205
  return { data: Buffer.concat(buffers) };
190
206
  }
191
- throw new Error(`The attachment type has been expressed as ${type.toUpperCase()} but cannot be resolved as one.`);
207
+ throw new common_1.SeyfertError('INVALID_ATTACHMENT_TYPE', {
208
+ metadata: {
209
+ ...(0, common_1.createValidationMetadata)('Buffer | ArrayBuffer | AsyncIterable<ArrayBuffer>', data),
210
+ detail: `The attachment type has been expressed as ${type.toUpperCase()} but cannot be resolved as one.`,
211
+ },
212
+ });
192
213
  }
193
214
  default: {
194
- throw new Error(`The attachment type has been expressed as ${type} but cannot be resolved as one.`);
215
+ throw new common_1.SeyfertError('INVALID_ATTACHMENT_TYPE', {
216
+ metadata: {
217
+ ...(0, common_1.createValidationMetadata)('url | path | buffer', type),
218
+ detail: `The attachment type has been expressed as ${type} but cannot be resolved as one.`,
219
+ },
220
+ });
195
221
  }
196
222
  }
197
223
  }
@@ -215,7 +241,15 @@ async function resolveImage(image) {
215
241
  const { data: { type, resolvable }, } = image;
216
242
  if (type && resolvable)
217
243
  return resolveBase64((await resolveAttachmentData(resolvable, type)).data);
218
- throw new Error(`The attachment type has been expressed as ${(type ?? 'Attachment').toUpperCase()} but cannot be resolved as one.`);
244
+ throw new common_1.SeyfertError('INVALID_ATTACHMENT_TYPE', {
245
+ metadata: {
246
+ ...(0, common_1.createValidationMetadata)('AttachmentBuilder with type and resolvable data', {
247
+ type,
248
+ resolvable,
249
+ }),
250
+ detail: `The attachment type has been expressed as ${(type ?? 'Attachment').toUpperCase()} but cannot be resolved as one.`,
251
+ },
252
+ });
219
253
  }
220
254
  if (image instanceof Attachment) {
221
255
  const response = await fetch(image.url);
@@ -47,7 +47,12 @@ class Button extends Base_1.BaseComponentBuilder {
47
47
  setEmoji(emoji) {
48
48
  const resolve = (0, common_1.resolvePartialEmoji)(emoji);
49
49
  if (!resolve)
50
- throw new Error('Invalid Emoji');
50
+ throw new common_1.SeyfertError('INVALID_EMOJI', {
51
+ metadata: {
52
+ ...(0, common_1.createValidationMetadata)('EmojiResolvable', emoji, { component: 'Button' }),
53
+ detail: 'Invalid Emoji',
54
+ },
55
+ });
51
56
  this.data.emoji =
52
57
  resolve;
53
58
  return this;
@@ -1,4 +1,4 @@
1
- import type { RestOrArray } from '../common';
1
+ import { type RestOrArray } from '../common';
2
2
  import { type APICheckboxGroupComponent, type APICheckboxGroupOption } from '../types';
3
3
  import { BaseComponentBuilder, type OptionValuesLength } from './Base';
4
4
  export declare class CheckboxGroup extends BaseComponentBuilder<APICheckboxGroupComponent> {
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CheckboxGroupOption = exports.CheckboxGroup = void 0;
4
+ const common_1 = require("../common");
4
5
  const types_1 = require("../types");
5
6
  const Base_1 = require("./Base");
6
7
  class CheckboxGroup extends Base_1.BaseComponentBuilder {
@@ -59,7 +60,14 @@ class CheckboxGroup extends Base_1.BaseComponentBuilder {
59
60
  const options = [...this.#options.map(option => option.toJSON()), ...(this.data.options ?? [])];
60
61
  const optionCount = options.length;
61
62
  if (optionCount < 2 || optionCount > 10) {
62
- throw new Error('RadioGroup must have between 2 and 10 options.');
63
+ throw new common_1.SeyfertError('INVALID_OPTIONS_LENGTH', {
64
+ metadata: {
65
+ ...(0, common_1.createValidationMetadata)('number of options between 2 and 10', optionCount, {
66
+ component: 'CheckboxGroup',
67
+ }),
68
+ detail: 'CheckboxGroup must have between 2 and 10 options.',
69
+ },
70
+ });
63
71
  }
64
72
  return {
65
73
  ...this.data,
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Label = void 0;
4
+ const common_1 = require("../common");
4
5
  const types_1 = require("../types");
5
6
  const _1 = require(".");
6
7
  const Base_1 = require("./Base");
@@ -25,7 +26,14 @@ class Label extends Base_1.BaseComponentBuilder {
25
26
  }
26
27
  toJSON() {
27
28
  if (!this.component)
28
- throw new Error('Cannot convert to JSON without a component.');
29
+ throw new common_1.SeyfertError('MISSING_COMPONENT', {
30
+ metadata: {
31
+ ...(0, common_1.createValidationMetadata)('component to be set before calling toJSON()', this.component, {
32
+ component: 'Label',
33
+ }),
34
+ detail: 'Cannot convert to JSON without a component.',
35
+ },
36
+ });
29
37
  return {
30
38
  ...this.data,
31
39
  component: this.component.toJSON(),
@@ -40,7 +40,12 @@ class PollBuilder {
40
40
  return { text: data.text };
41
41
  const resolve = (0, common_1.resolvePartialEmoji)(data.emoji);
42
42
  if (!resolve)
43
- throw new Error('Invalid Emoji');
43
+ throw new common_1.SeyfertError('INVALID_EMOJI', {
44
+ metadata: {
45
+ ...(0, common_1.createValidationMetadata)('EmojiResolvable', data.emoji, { component: 'PollBuilder' }),
46
+ detail: 'Invalid Emoji',
47
+ },
48
+ });
44
49
  return { text: data.text, emoji: resolve };
45
50
  }
46
51
  }
@@ -1,4 +1,4 @@
1
- import type { RestOrArray } from '../common';
1
+ import { type RestOrArray } from '../common';
2
2
  import { type APIRadioGroupComponent, type APIRadioGroupOption } from '../types';
3
3
  import { BaseComponentBuilder } from './Base';
4
4
  export declare class RadioGroup extends BaseComponentBuilder<APIRadioGroupComponent> {
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RadioGroupOption = exports.RadioGroup = void 0;
4
+ const common_1 = require("../common");
4
5
  const types_1 = require("../types");
5
6
  const Base_1 = require("./Base");
6
7
  class RadioGroup extends Base_1.BaseComponentBuilder {
@@ -47,7 +48,14 @@ class RadioGroup extends Base_1.BaseComponentBuilder {
47
48
  const options = [...this.#options.map(option => option.data), ...(this.data.options ?? [])];
48
49
  const optionCount = options.length;
49
50
  if (optionCount < 2 || optionCount > 10) {
50
- throw new Error('RadioGroup must have between 2 and 10 options.');
51
+ throw new common_1.SeyfertError('INVALID_OPTIONS_LENGTH', {
52
+ metadata: {
53
+ ...(0, common_1.createValidationMetadata)('number of options between 2 and 10', optionCount, {
54
+ component: 'RadioGroup',
55
+ }),
56
+ detail: 'RadioGroup must have between 2 and 10 options.',
57
+ },
58
+ });
51
59
  }
52
60
  return {
53
61
  ...this.data,
@@ -1,4 +1,4 @@
1
- import type { RestOrArray } from '../common';
1
+ import { type RestOrArray } from '../common';
2
2
  import { type APISectionComponent } from '../types';
3
3
  import { type Button } from '.';
4
4
  import { BaseComponentBuilder } from './Base';
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Section = void 0;
4
+ const common_1 = require("../common");
4
5
  const types_1 = require("../types");
5
6
  const _1 = require(".");
6
7
  const Base_1 = require("./Base");
@@ -41,7 +42,14 @@ class Section extends Base_1.BaseComponentBuilder {
41
42
  */
42
43
  toJSON() {
43
44
  if (!this.accessory)
44
- throw new Error('Cannot convert to JSON without an accessory.');
45
+ throw new common_1.SeyfertError('MISSING_ACCESSORY', {
46
+ metadata: {
47
+ ...(0, common_1.createValidationMetadata)('accessory to be set before calling toJSON()', this.accessory, {
48
+ component: 'Section',
49
+ }),
50
+ detail: 'Cannot convert to JSON without an accessory.',
51
+ },
52
+ });
45
53
  return {
46
54
  ...this.data,
47
55
  components: this.components.map(component => component.toJSON()),
@@ -1,4 +1,4 @@
1
- import type { EmojiResolvable, RestOrArray } from '../common';
1
+ import { type EmojiResolvable, type RestOrArray } from '../common';
2
2
  import { type APIChannelSelectComponent, type APIMentionableSelectComponent, type APIRoleSelectComponent, type APISelectMenuComponent, type APISelectMenuOption, type APIStringSelectComponent, type APIUserSelectComponent, type ChannelType, SelectMenuDefaultValueType } from '../types';
3
3
  import { BaseComponentBuilder, type OptionValuesLength } from './Base';
4
4
  export type BuilderSelectMenus = RoleSelectMenu | UserSelectMenu | MentionableSelectMenu | ChannelSelectMenu | StringSelectMenu;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.StringSelectOption = exports.StringSelectMenu = exports.ChannelSelectMenu = exports.MentionableSelectMenu = exports.RoleSelectMenu = exports.UserSelectMenu = exports.SelectMenu = void 0;
4
+ const common_1 = require("../common");
4
5
  const utils_1 = require("../common/it/utils");
5
6
  const types_1 = require("../types");
6
7
  const Base_1 = require("./Base");
@@ -318,7 +319,12 @@ class StringSelectOption {
318
319
  setEmoji(emoji) {
319
320
  const resolve = (0, utils_1.resolvePartialEmoji)(emoji);
320
321
  if (!resolve)
321
- throw new Error('Invalid Emoji');
322
+ throw new common_1.SeyfertError('INVALID_EMOJI', {
323
+ metadata: {
324
+ ...(0, common_1.createValidationMetadata)('EmojiResolvable', emoji, { component: 'StringSelectOption' }),
325
+ detail: 'Invalid Emoji',
326
+ },
327
+ });
322
328
  this.data.emoji = resolve;
323
329
  return this;
324
330
  }
@@ -36,7 +36,7 @@ class WorkerAdapter {
36
36
  return new Promise((res, rej) => {
37
37
  const timeout = setTimeout(() => {
38
38
  this.promises.delete(nonce);
39
- rej(new Error('Timeout cache request'));
39
+ rej(new common_1.SeyfertError('CACHE_TIMEOUT', { metadata: { ...{ nonce, method }, detail: 'Timeout cache request' } }));
40
40
  }, 60e3);
41
41
  this.promises.set(nonce, { resolve: res, timeout });
42
42
  });