magmastream 2.9.1 → 2.9.2-dev.2

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.
@@ -11,6 +11,7 @@ const RedisQueue_1 = require("../statestorage/RedisQueue");
11
11
  const Enums_1 = require("./Enums");
12
12
  const ws_1 = require("ws");
13
13
  const JsonQueue_1 = require("../statestorage/JsonQueue");
14
+ const MagmastreamError_1 = require("./MagmastreamError");
14
15
  class Player {
15
16
  options;
16
17
  /** The Queue for the Player. */
@@ -75,8 +76,12 @@ class Player {
75
76
  // If the Manager is not initiated, throw an error.
76
77
  if (!this.manager)
77
78
  this.manager = Utils_1.Structure.get("Player")._manager;
78
- if (!this.manager)
79
- throw new RangeError("Manager has not been initiated.");
79
+ if (!this.manager) {
80
+ throw new MagmastreamError_1.MagmaStreamError({
81
+ code: Enums_1.MagmaStreamErrorCode.GENERAL_INVALID_MANAGER,
82
+ message: "Manager instance is required.",
83
+ });
84
+ }
80
85
  this.clusterId = this.manager.options.clusterId || 0;
81
86
  // Check the player options for errors.
82
87
  (0, playerCheck_1.default)(options);
@@ -102,8 +107,13 @@ class Player {
102
107
  const node = this.manager.nodes.get(options.nodeIdentifier);
103
108
  this.node = node || this.manager.useableNode;
104
109
  // If no node is available, throw an error.
105
- if (!this.node)
106
- throw new RangeError("No available nodes.");
110
+ if (!this.node) {
111
+ throw new MagmastreamError_1.MagmaStreamError({
112
+ code: Enums_1.MagmaStreamErrorCode.MANAGER_NO_NODES,
113
+ message: "No available nodes for the player found.",
114
+ context: { guildId: this.guildId },
115
+ });
116
+ }
107
117
  // Initialize the queue with the guild ID and manager.
108
118
  switch (this.manager.options.stateStorage.type) {
109
119
  case Enums_1.StateStorageType.Redis:
@@ -169,7 +179,11 @@ class Player {
169
179
  connect() {
170
180
  // Check if the voice channel has been set.
171
181
  if (!this.voiceChannelId) {
172
- throw new RangeError("No voice channel has been set. You must use the `setVoiceChannelId()` method to set the voice channel before connecting.");
182
+ throw new MagmastreamError_1.MagmaStreamError({
183
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_CONFIG,
184
+ message: "No voice channel has been set. You must set the voice channel before connecting.",
185
+ context: { voiceChannelId: this.voiceChannelId },
186
+ });
173
187
  }
174
188
  // Set the player state to connecting.
175
189
  this.state = Enums_1.StateTypes.Connecting;
@@ -268,8 +282,12 @@ class Player {
268
282
  */
269
283
  setVoiceChannelId(channel) {
270
284
  // Validate the channel parameter
271
- if (typeof channel !== "string")
272
- throw new TypeError("Channel must be a non-empty string.");
285
+ if (typeof channel !== "string") {
286
+ throw new MagmastreamError_1.MagmaStreamError({
287
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_CONFIG,
288
+ message: "Channel must be a non-empty string.",
289
+ });
290
+ }
273
291
  // Clone the current player state for comparison
274
292
  const oldPlayer = this ? { ...this } : null;
275
293
  // Update the player voice channel
@@ -300,8 +318,12 @@ class Player {
300
318
  */
301
319
  setTextChannelId(channel) {
302
320
  // Validate the channel parameter
303
- if (typeof channel !== "string")
304
- throw new TypeError("Channel must be a non-empty string.");
321
+ if (typeof channel !== "string") {
322
+ throw new MagmastreamError_1.MagmaStreamError({
323
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_CONFIG,
324
+ message: "Channel must be a non-empty string.",
325
+ });
326
+ }
305
327
  // Clone the current player state for comparison
306
328
  const oldPlayer = this ? { ...this } : null;
307
329
  // Update the text channel property
@@ -328,7 +350,10 @@ class Player {
328
350
  */
329
351
  setNowPlayingMessage(message) {
330
352
  if (!message) {
331
- throw new TypeError("You must provide the message of the now playing message.");
353
+ throw new MagmastreamError_1.MagmaStreamError({
354
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_NOW_PLAYING_MESSAGE,
355
+ message: "You must provide the message of the now playing message.",
356
+ });
332
357
  }
333
358
  this.nowPlayingMessage = message;
334
359
  return this.nowPlayingMessage;
@@ -337,8 +362,12 @@ class Player {
337
362
  if (typeof optionsOrTrack !== "undefined" && Utils_1.TrackUtils.validate(optionsOrTrack)) {
338
363
  await this.queue.setCurrent(optionsOrTrack);
339
364
  }
340
- if (!(await this.queue.getCurrent()))
341
- throw new RangeError("No current track.");
365
+ if (!(await this.queue.getCurrent())) {
366
+ throw new MagmastreamError_1.MagmaStreamError({
367
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_QUEUE_EMPTY,
368
+ message: "The queue is empty.",
369
+ });
370
+ }
342
371
  const finalOptions = playOptions
343
372
  ? playOptions
344
373
  : ["startTime", "endTime", "noReplace"].every((v) => Object.keys(optionsOrTrack || {}).includes(v))
@@ -369,11 +398,17 @@ class Player {
369
398
  */
370
399
  setAutoplay(autoplayState, AutoplayUser, tries) {
371
400
  if (typeof autoplayState !== "boolean") {
372
- throw new Error("autoplayState must be a boolean.");
401
+ throw new MagmastreamError_1.MagmaStreamError({
402
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_AUTOPLAY,
403
+ message: "autoplayState must be a boolean.",
404
+ });
373
405
  }
374
406
  if (autoplayState) {
375
407
  if (!AutoplayUser) {
376
- throw new Error("AutoplayUser must be provided when enabling autoplay.");
408
+ throw new MagmastreamError_1.MagmaStreamError({
409
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_AUTOPLAY,
410
+ message: "AutoplayUser must be provided when enabling autoplay.",
411
+ });
377
412
  }
378
413
  this.autoplayTries = tries && typeof tries === "number" && tries > 0 ? tries : 3; // Default to 3 if invalid
379
414
  this.isAutoplay = true;
@@ -407,28 +442,46 @@ class Player {
407
442
  }
408
443
  /**
409
444
  * Sets the volume of the player.
410
- * @param {number} volume - The new volume. Must be between 0 and 1000.
445
+ * @param {number} volume - The new volume. Must be between 0 and 500 when using filter mode (100 = 100%).
411
446
  * @returns {Promise<Player>} - The updated player.
412
447
  * @throws {TypeError} If the volume is not a number.
413
- * @throws {RangeError} If the volume is not between 0 and 1000.
448
+ * @throws {RangeError} If the volume is not between 0 and 500 when using filter mode (100 = 100%).
414
449
  * @emits {PlayerStateUpdate} - Emitted when the volume is changed.
415
450
  * @example
416
451
  * player.setVolume(50);
417
- * player.setVolume(50, { gradual: true, interval: 50, step: 5 });
418
452
  */
419
453
  async setVolume(volume) {
420
- if (isNaN(volume))
421
- throw new TypeError("Volume must be a number.");
422
- if (volume < 0 || volume > 1000)
423
- throw new RangeError("Volume must be between 0 and 1000.");
454
+ if (isNaN(volume)) {
455
+ throw new MagmastreamError_1.MagmaStreamError({
456
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_VOLUME,
457
+ message: "Volume must be a number.",
458
+ });
459
+ }
460
+ if (this.options.applyVolumeAsFilter) {
461
+ if (volume < 0 || volume > 500) {
462
+ throw new MagmastreamError_1.MagmaStreamError({
463
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_VOLUME,
464
+ message: "Volume must be between 0 and 500 when using filter mode (100 = 100%).",
465
+ });
466
+ }
467
+ }
468
+ else {
469
+ if (volume < 0 || volume > 1000) {
470
+ throw new MagmastreamError_1.MagmaStreamError({
471
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_VOLUME,
472
+ message: "Volume must be between 0 and 1000.",
473
+ });
474
+ }
475
+ }
424
476
  const oldVolume = this.volume;
425
477
  const oldPlayer = { ...this };
426
- const data = this.options.applyVolumeAsFilter ? { filters: { volume } } : { volume };
478
+ const data = this.options.applyVolumeAsFilter ? { filters: { volume: volume / 100 } } : { volume };
427
479
  await this.node.rest.updatePlayer({
428
480
  guildId: this.options.guildId,
429
481
  data,
430
482
  });
431
483
  this.volume = volume;
484
+ this.options.volume = volume;
432
485
  this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this, {
433
486
  changeType: Enums_1.PlayerStateEventTypes.VolumeChange,
434
487
  details: {
@@ -473,8 +526,12 @@ class Player {
473
526
  */
474
527
  setTrackRepeat(repeat) {
475
528
  // Ensure the repeat parameter is a boolean
476
- if (typeof repeat !== "boolean")
477
- throw new TypeError('Repeat can only be "true" or "false".');
529
+ if (typeof repeat !== "boolean") {
530
+ throw new MagmastreamError_1.MagmaStreamError({
531
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_REPEAT,
532
+ message: "Repeat must be a boolean.",
533
+ });
534
+ }
478
535
  // Clone the current player state for event emission
479
536
  const oldPlayer = this ? { ...this } : null;
480
537
  if (repeat) {
@@ -509,8 +566,12 @@ class Player {
509
566
  */
510
567
  setQueueRepeat(repeat) {
511
568
  // Ensure the repeat parameter is a boolean
512
- if (typeof repeat !== "boolean")
513
- throw new TypeError('Repeat can only be "true" or "false".');
569
+ if (typeof repeat !== "boolean") {
570
+ throw new MagmastreamError_1.MagmaStreamError({
571
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_REPEAT,
572
+ message: "Repeat must be a boolean.",
573
+ });
574
+ }
514
575
  // Get the current player state
515
576
  const oldPlayer = this ? { ...this } : null;
516
577
  // Update the player state
@@ -547,11 +608,17 @@ class Player {
547
608
  async setDynamicRepeat(repeat, ms) {
548
609
  // Validate the repeat parameter
549
610
  if (typeof repeat !== "boolean") {
550
- throw new TypeError('Repeat can only be "true" or "false".');
611
+ throw new MagmastreamError_1.MagmaStreamError({
612
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_REPEAT,
613
+ message: "Repeat must be a boolean.",
614
+ });
551
615
  }
552
616
  // Ensure the queue has more than one track for dynamic repeat
553
617
  if ((await this.queue.size()) <= 1) {
554
- throw new RangeError("The queue size must be greater than 1.");
618
+ throw new MagmastreamError_1.MagmaStreamError({
619
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_REPEAT,
620
+ message: "The queue size must be greater than 1.",
621
+ });
555
622
  }
556
623
  // Clone the current player state for comparison
557
624
  const oldPlayer = this ? { ...this } : null;
@@ -626,8 +693,12 @@ class Player {
626
693
  const oldPlayer = { ...this };
627
694
  let removedTracks = [];
628
695
  if (typeof amount === "number" && amount > 1) {
629
- if (amount > (await this.queue.size()))
630
- throw new RangeError("Cannot skip more than the queue length.");
696
+ if (amount > (await this.queue.size())) {
697
+ throw new MagmastreamError_1.MagmaStreamError({
698
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_QUEUE_EMPTY,
699
+ message: "The queue size must be greater than 1.",
700
+ });
701
+ }
631
702
  removedTracks = await this.queue.getSlice(0, amount - 1);
632
703
  await this.queue.modifyAt(0, amount - 1);
633
704
  }
@@ -655,8 +726,12 @@ class Player {
655
726
  */
656
727
  async pause(pause) {
657
728
  // Validate the pause parameter to ensure it's a boolean.
658
- if (typeof pause !== "boolean")
659
- throw new RangeError('Pause can only be "true" or "false".');
729
+ if (typeof pause !== "boolean") {
730
+ throw new MagmastreamError_1.MagmaStreamError({
731
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_PAUSE,
732
+ message: "Pause must be a boolean.",
733
+ });
734
+ }
660
735
  // If the pause state is already as desired or there are no tracks, return early.
661
736
  if (this.paused === pause || !this.queue.totalSize)
662
737
  return this;
@@ -691,18 +766,20 @@ class Player {
691
766
  * @emits {PlayerStateUpdate} - With {@link PlayerStateEventTypes.TrackChange} as the change type.
692
767
  */
693
768
  async previous() {
694
- // Get and remove the most recent previous track
769
+ // Pop the most recent previous track (from tail)
695
770
  const lastTrack = await this.queue.popPrevious();
696
771
  if (!lastTrack) {
697
772
  await this.queue.clearPrevious();
698
- throw new Error("No previous track available.");
773
+ throw new MagmastreamError_1.MagmaStreamError({
774
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_PREVIOUS_EMPTY,
775
+ message: "Previous queue is empty.",
776
+ });
699
777
  }
700
778
  // Capture the current state of the player before making changes.
701
779
  const oldPlayer = { ...this };
702
- // Set skip flag so trackEnd doesn't add current to previous
780
+ // Prevent re-adding the current track
703
781
  this.set("skipFlag", true);
704
782
  await this.play(lastTrack);
705
- // Emit state update
706
783
  this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this, {
707
784
  changeType: Enums_1.PlayerStateEventTypes.TrackChange,
708
785
  details: {
@@ -726,7 +803,10 @@ class Player {
726
803
  position = Number(position);
727
804
  // Check if the position is valid.
728
805
  if (isNaN(position)) {
729
- throw new RangeError("Position must be a number.");
806
+ throw new MagmastreamError_1.MagmaStreamError({
807
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_SEEK,
808
+ message: "Position must be a number.",
809
+ });
730
810
  }
731
811
  // Get the old player state.
732
812
  const oldPlayer = this ? { ...this } : null;
@@ -790,8 +870,14 @@ class Player {
790
870
  */
791
871
  async moveNode(identifier) {
792
872
  const node = this.manager.nodes.get(identifier);
793
- if (!node)
794
- throw new Error(`Node with identifier ${identifier} not found`);
873
+ if (!node) {
874
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Tried to move to non-existent node: ${identifier}`);
875
+ throw new MagmastreamError_1.MagmaStreamError({
876
+ code: Enums_1.MagmaStreamErrorCode.MANAGER_NODE_NOT_FOUND,
877
+ message: "Node not found.",
878
+ context: { identifier },
879
+ });
880
+ }
795
881
  if (this.state !== Enums_1.StateTypes.Connected) {
796
882
  return this;
797
883
  }
@@ -806,7 +892,12 @@ class Player {
806
892
  const token = this.voiceState?.event?.token;
807
893
  const endpoint = this.voiceState?.event?.endpoint;
808
894
  if (!sessionId || !token || !endpoint) {
809
- throw new Error(`Voice state is not properly initialized for player ${this.guildId}. The bot might not be connected to a voice channel.`);
895
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Voice state is not properly initialized for player ${this.guildId}. The bot might not be connected to a voice channel.`);
896
+ throw new MagmastreamError_1.MagmaStreamError({
897
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_STATE_INVALID,
898
+ message: `Voice state is not properly initialized. The bot might not be connected to a voice channel.`,
899
+ context: { guildId: this.guildId },
900
+ });
810
901
  }
811
902
  await this.node.rest.destroyPlayer(this.guildId).catch(() => { });
812
903
  this.manager.players.delete(this.guildId);
@@ -818,8 +909,17 @@ class Player {
818
909
  });
819
910
  await this.filters.updateFilters();
820
911
  }
821
- catch (error) {
822
- throw new Error(`Failed to move player to node ${identifier}: ${error}`);
912
+ catch (err) {
913
+ const error = err instanceof MagmastreamError_1.MagmaStreamError
914
+ ? err
915
+ : new MagmastreamError_1.MagmaStreamError({
916
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_MOVE_FAILED,
917
+ message: "Error moving player to node.",
918
+ cause: err,
919
+ context: { guildId: this.guildId },
920
+ });
921
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, error);
922
+ console.error(error);
823
923
  }
824
924
  }
825
925
  /**
@@ -831,12 +931,24 @@ class Player {
831
931
  * @returns {Promise<Player>} - The new player instance.
832
932
  */
833
933
  async switchGuild(newOptions, force = false) {
834
- if (!newOptions.guildId)
835
- throw new Error("guildId is required");
836
- if (!newOptions.voiceChannelId)
837
- throw new Error("Voice channel ID is required");
838
- if (!newOptions.textChannelId)
839
- throw new Error("Text channel ID is required");
934
+ if (!newOptions.guildId) {
935
+ throw new MagmastreamError_1.MagmaStreamError({
936
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_CONFIG,
937
+ message: "guildId is required for switchGuild",
938
+ });
939
+ }
940
+ if (!newOptions.voiceChannelId) {
941
+ throw new MagmastreamError_1.MagmaStreamError({
942
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_CONFIG,
943
+ message: "voiceChannelId is required for switchGuild",
944
+ });
945
+ }
946
+ if (!newOptions.textChannelId) {
947
+ throw new MagmastreamError_1.MagmaStreamError({
948
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_CONFIG,
949
+ message: "textChannelId is required for switchGuild",
950
+ });
951
+ }
840
952
  // Check if a player already exists for the new guild
841
953
  let newPlayer = this.manager.getPlayer(newOptions.guildId);
842
954
  // If the player already exists and force is false, return the existing player
@@ -917,18 +1029,26 @@ class Player {
917
1029
  // Return the cloned player
918
1030
  return clonedPlayer;
919
1031
  }
1032
+ /**
1033
+ * Retrieves the data associated with the player.
1034
+ * @returns {Record<string, unknown>} - The data associated with the player.
1035
+ */
1036
+ getData() {
1037
+ return this.data;
1038
+ }
1039
+ /**
1040
+ * Retrieves the dynamic loop interval of the player.
1041
+ * @returns {NodeJS.Timeout | null} - The dynamic loop interval of the player.
1042
+ */
1043
+ getDynamicLoopIntervalPublic() {
1044
+ return this.dynamicLoopInterval;
1045
+ }
920
1046
  /**
921
1047
  * Retrieves the current lyrics for the playing track.
922
1048
  * @param skipTrackSource - Indicates whether to skip the track source when fetching lyrics.
923
1049
  * @returns {Promise<Lyrics>} - The lyrics of the current track.
924
- * @throws {RangeError} - If the 'lavalyrics-plugin' is not available on the Lavalink node.
925
1050
  */
926
1051
  async getCurrentLyrics(skipTrackSource = false) {
927
- // Check if the 'lavalyrics-plugin' is available on the node
928
- const hasLyricsPlugin = this.node.info.plugins.some((plugin) => plugin.name === "lavalyrics-plugin");
929
- if (!hasLyricsPlugin) {
930
- throw new RangeError(`There is no lavalyrics-plugin available in the Lavalink node: ${this.node.options.identifier}`);
931
- }
932
1052
  // Fetch the lyrics for the current track from the Lavalink node
933
1053
  let result = (await this.node.getLyrics(await this.queue.getCurrent(), skipTrackSource));
934
1054
  // If no lyrics are found, return a default empty lyrics object
@@ -949,8 +1069,13 @@ class Player {
949
1069
  * @throws {Error} - If the node is not a NodeLink.
950
1070
  */
951
1071
  async setupVoiceReceiver() {
952
- if (!this.node.isNodeLink)
953
- throw new Error("This function is only available for NodeLinks");
1072
+ if (!this.node.isNodeLink) {
1073
+ throw new MagmastreamError_1.MagmaStreamError({
1074
+ code: Enums_1.MagmaStreamErrorCode.NODE_PROTOCOL_ERROR,
1075
+ message: `The node is not a NodeLink, cannot setup voice receiver.`,
1076
+ context: { identifier: this.node.options.identifier },
1077
+ });
1078
+ }
954
1079
  if (this.voiceReceiverWsClient)
955
1080
  await this.removeVoiceReceiver();
956
1081
  const headers = {
@@ -972,8 +1097,13 @@ class Player {
972
1097
  * @throws {Error} - If the node is not a NodeLink.
973
1098
  */
974
1099
  async removeVoiceReceiver() {
975
- if (!this.node.isNodeLink)
976
- throw new Error("This function is only available for NodeLinks");
1100
+ if (!this.node.isNodeLink) {
1101
+ throw new MagmastreamError_1.MagmaStreamError({
1102
+ code: Enums_1.MagmaStreamErrorCode.NODE_PROTOCOL_ERROR,
1103
+ message: `The node is not a NodeLink, cannot remove voice receiver.`,
1104
+ context: { identifier: this.node.options.identifier },
1105
+ });
1106
+ }
977
1107
  if (this.voiceReceiverWsClient) {
978
1108
  this.voiceReceiverWsClient.close(1000, "destroy");
979
1109
  this.voiceReceiverWsClient.removeAllListeners();
@@ -999,8 +1129,13 @@ class Player {
999
1129
  */
1000
1130
  async reconnectVoiceReceiver() {
1001
1131
  this.voiceReceiverReconnectTimeout = setTimeout(async () => {
1002
- if (this.voiceReceiverAttempt > this.voiceReceiverReconnectTries)
1003
- throw new Error("Failed to reconnect to voice receiver");
1132
+ if (this.voiceReceiverAttempt > this.voiceReceiverReconnectTries) {
1133
+ throw new MagmastreamError_1.MagmaStreamError({
1134
+ code: Enums_1.MagmaStreamErrorCode.PLAYER_VOICE_RECEIVER_ERROR,
1135
+ message: `Failed to reconnect to voice receiver for player ${this.guildId}`,
1136
+ context: { identifier: this.node.options.identifier },
1137
+ });
1138
+ }
1004
1139
  this.voiceReceiverWsClient?.removeAllListeners();
1005
1140
  this.voiceReceiverWsClient = null;
1006
1141
  this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[PLAYER] Reconnecting to voice receiver for player ${this.guildId}`);
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
5
5
  const axios_1 = tslib_1.__importDefault(require("axios"));
6
6
  const Enums_1 = require("./Enums");
7
7
  const Utils_1 = require("./Utils");
8
+ const MagmastreamError_1 = require("./MagmastreamError");
8
9
  /** Handles the requests sent to the Lavalink REST API. */
9
10
  class Rest {
10
11
  /** The Node that this Rest instance is connected to. */
@@ -38,12 +39,12 @@ class Rest {
38
39
  return this.sessionId;
39
40
  }
40
41
  /**
41
- * Retrieves all the players that are currently running on the node.
42
+ * Retrieves one the player that is currently running on the node.
42
43
  * @returns {Promise<unknown>} Returns the result of the GET request.
43
44
  */
44
- async getAllPlayers() {
45
+ async getPlayer(guildId) {
45
46
  // Send a GET request to the Lavalink Node to retrieve all the players.
46
- const result = await this.get(`/v4/sessions/${this.sessionId}/players`);
47
+ const result = (await this.get(`/v4/sessions/${this.sessionId}/players/${guildId}`));
47
48
  // Log the result of the request.
48
49
  this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] Getting all players on node: ${this.node.options.identifier} : ${Utils_1.JSONUtils.safe(result, 2)}`);
49
50
  // Return the result of the request.
@@ -93,7 +94,7 @@ class Rest {
93
94
  * @returns {Promise<unknown>} The response data of the request.
94
95
  */
95
96
  async request(method, endpoint, body) {
96
- this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] ${method} api call for endpoint: ${endpoint} with data: ${Utils_1.JSONUtils.safe(body, 2)}`);
97
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] ${method} request to ${endpoint} with body: ${Utils_1.JSONUtils.safe(body, 2)}`);
97
98
  const config = {
98
99
  method,
99
100
  url: this.url + endpoint,
@@ -108,19 +109,29 @@ class Rest {
108
109
  const response = await (0, axios_1.default)(config);
109
110
  return response.data;
110
111
  }
111
- catch (error) {
112
+ catch (err) {
113
+ const error = err;
112
114
  if (!error.response) {
113
- console.error(`[REST] No response from node: ${error.message}`);
114
- return null;
115
+ throw new MagmastreamError_1.MagmaStreamError({
116
+ code: Enums_1.MagmaStreamErrorCode.REST_REQUEST_FAILED,
117
+ message: `No response from node ${this.node.options.identifier}: ${error.message}`,
118
+ });
115
119
  }
116
- if (error.response.data?.message === "Guild not found") {
120
+ const data = error.response.data;
121
+ if (data?.message === "Guild not found") {
117
122
  return [];
118
123
  }
119
- else if (error.response.status === 404) {
120
- await this.node.destroy();
121
- await this.node.manager.createNode(this.node.options).connect();
124
+ if (error.response.status === 401) {
125
+ throw new MagmastreamError_1.MagmaStreamError({
126
+ code: Enums_1.MagmaStreamErrorCode.REST_UNAUTHORIZED,
127
+ message: `Unauthorized access to node ${this.node.options.identifier}`,
128
+ });
122
129
  }
123
- return null;
130
+ const dataMessage = typeof data === "string" ? data : data?.message ? data.message : Utils_1.JSONUtils.safe(data, 2);
131
+ throw new MagmastreamError_1.MagmaStreamError({
132
+ code: Enums_1.MagmaStreamErrorCode.REST_REQUEST_FAILED,
133
+ message: `Request to node ${this.node.options.identifier} failed with status ${error.response.status}: ${dataMessage}`,
134
+ });
124
135
  }
125
136
  }
126
137
  /**