(interaction, embed, context = {})
| 204 | } |
| 205 | |
| 206 | async function sendErrorResponse(interaction, embed, context = {}) { |
| 207 | try { |
| 208 | if (!interaction || !interaction.id) { |
| 209 | logger.warn('Interaction was null or invalid when handling error', { |
| 210 | event: 'interaction.error.invalid_interaction', |
| 211 | errorCode: ErrorCodes.INTERACTION_INVALID, |
| 212 | remediationHint: getErrorMetadata(ErrorCodes.INTERACTION_INVALID).remediation, |
| 213 | traceId: context.traceId |
| 214 | }); |
| 215 | return false; |
| 216 | } |
| 217 | |
| 218 | const coordinator = InteractionHelper.getCoordinator(interaction); |
| 219 | if (coordinator?.isUsageFinalized()) { |
| 220 | return false; |
| 221 | } |
| 222 | |
| 223 | if (interaction.createdTimestamp && (Date.now() - interaction.createdTimestamp) > 14 * 60 * 1000) { |
| 224 | logger.warn('Interaction expired before error handler could send response', { |
| 225 | event: 'interaction.error.expired', |
| 226 | errorCode: ErrorCodes.INTERACTION_EXPIRED, |
| 227 | remediationHint: getErrorMetadata(ErrorCodes.INTERACTION_EXPIRED).remediation, |
| 228 | traceId: context.traceId, |
| 229 | guildId: interaction.guildId, |
| 230 | userId: interaction.user?.id, |
| 231 | command: interaction.commandName || context.command |
| 232 | }); |
| 233 | return false; |
| 234 | } |
| 235 | |
| 236 | const errorMessage = { embeds: [embed] }; |
| 237 | |
| 238 | if (interaction._isPrefixCommand) { |
| 239 | if (coordinator?.hasResponded()) { |
| 240 | await coordinator.edit(errorMessage); |
| 241 | } else { |
| 242 | await coordinator?.respond(errorMessage); |
| 243 | } |
| 244 | return true; |
| 245 | } |
| 246 | |
| 247 | const useEphemeral = context.ephemeral !== false; |
| 248 | if (useEphemeral && !interaction.deferred && !interaction.replied) { |
| 249 | errorMessage.flags = MessageFlags.Ephemeral; |
| 250 | } |
| 251 | |
| 252 | if (interaction.deferred || interaction.replied) { |
| 253 | await interaction.editReply(errorMessage); |
| 254 | } else { |
| 255 | await interaction.reply(errorMessage); |
| 256 | } |
| 257 | |
| 258 | return true; |
| 259 | } catch (replyError) { |
| 260 | if (replyError.code === 40060 || replyError.code === 10062 || replyError.code === 50027) { |
| 261 | logger.warn('Interaction already acknowledged, expired, or token invalid; cannot send error response:', { |
| 262 | event: 'interaction.error.response_unavailable', |
| 263 | errorCode: String(replyError.code), |
no test coverage detected