(interaction, options = {})
| 104 | } |
| 105 | |
| 106 | static async safeDefer(interaction, options = {}) { |
| 107 | try { |
| 108 | if (interaction.deferred || interaction.replied) { |
| 109 | return true; |
| 110 | } |
| 111 | |
| 112 | const coordinator = this.getCoordinator(interaction); |
| 113 | if (coordinator?.isUsageFinalized()) { |
| 114 | return false; |
| 115 | } |
| 116 | |
| 117 | if (interaction._isPrefixCommand) { |
| 118 | return coordinator?.deferLocal() ?? false; |
| 119 | } |
| 120 | |
| 121 | if (!this.isInteractionValid(interaction)) { |
| 122 | logger.warn(`Interaction ${interaction.id} has expired before defer, ignoring`); |
| 123 | return false; |
| 124 | } |
| 125 | |
| 126 | await interaction.deferReply(options); |
| 127 | return true; |
| 128 | } catch (error) { |
| 129 | if (isInteractionUnavailableError(error)) { |
| 130 | logger.warn(`Interaction ${interaction.id} unavailable during defer:`, error.message); |
| 131 | return false; |
| 132 | } |
| 133 | if (error.name === 'InteractionAlreadyReplied' || error.code === 40060) { |
| 134 | logger.warn(`Interaction ${interaction.id} already acknowledged during defer:`, error.message); |
| 135 | return true; |
| 136 | } |
| 137 | logger.error('Failed to defer reply:', error); |
| 138 | return false; |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | static async safeEditReply(interaction, options) { |
| 143 | try { |
no test coverage detected