Phase 439: structured message.* and reaction.* platform error logs (v0.8.402)

Wrap sendMessage, editMessage, deleteMessage, and toggleReaction with log.time
spans and message.* / reaction.toggle error records on failure.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-05-23 18:55:38 -04:00
co-authored by Cursor
parent 1d00c2311c
commit 35ac3557a9
2 changed files with 74 additions and 26 deletions
+2
View File
@@ -143,6 +143,8 @@ Primary consumer: `apps/pearcord/index.js` sidecar reading pear-pipe JSON.
**v0.8.400:** `createChannelWebhook`/`deleteChannelWebhook`/`executeChannelWebhook` log `webhook.*` spans and errors; `registerSlashCommands`/`deleteSlashCommand`/`executeSlashCommand` log `slash.*` spans and errors.
**v0.8.402:** `sendMessage`/`editMessage`/`deleteMessage` log `message.*` spans and errors; `toggleReaction` logs `reaction.toggle` span and `reaction.toggle error` on failure.
**v0.8.401:** `createGuildCustomRole`/`updateGuildCustomRole`/`deleteGuildCustomRole`/`reorderGuildCustomRoles`/`setMemberCustomRoles` log `role.*` spans and errors; `upsertChannelPermissionOverwrite`/`deleteChannelPermissionOverwrite` log `permission.overwrite*` spans and errors.
**v0.8.252:** Guild search mesh skipped when `guildOpenNoViewableChannels`; emoji batch prefetch skips negative miss TTL; sticker gossip prefetch gated on `attachments`; `session.startup` logs INFO when initial guild mesh flush was bounded. Smoke: `test:guild-search-no-viewable-skip`, `test:sticker-prefetch-attachments-ready`.
+49 -3
View File
@@ -10071,12 +10071,24 @@ class PearcordPlatform extends EventEmitter {
}
async sendMessage (content, opts = {}) {
if (this._readOnly) throw new Error('read-only companion mode cannot send messages')
if (!this.messages) throw new Error('no channel')
if (this.mode === 'guild' && parseSlashInvocation(content)) {
return this.executeSlashCommand(content, opts)
}
return this._sendPlainMessage(content, opts)
const span = this.log.time('message.send', { channelId: this.activeChannelId })
try {
if (this._readOnly) throw new Error('read-only companion mode cannot send messages')
if (!this.messages) throw new Error('no channel')
const msg = await this._sendPlainMessage(content, opts)
span.end({ messageId: msg?.id })
return msg
} catch (err) {
this.log.error('message.send error', {
channelId: this.activeChannelId,
error: err?.message || String(err)
})
span.fail(err)
throw err
}
}
_onGuildTyping (payload) {
@@ -10189,12 +10201,23 @@ class PearcordPlatform extends EventEmitter {
}
async editMessage (messageId, content) {
const span = this.log.time('message.edit', { messageId })
try {
await this._assertCanModifyMessage(messageId, 'edit')
const msg = await this.messages.edit(messageId, content)
if (this.mode === 'dm' && this.dm) this.dm.gossipMessageUpdate(msg)
else if (this.guild) this.guild.gossipMessageUpdate(msg)
this.emit('message', msg)
span.end({ messageId: msg?.id })
return msg
} catch (err) {
this.log.error('message.edit error', {
messageId,
error: err?.message || String(err)
})
span.fail(err)
throw err
}
}
async createCategory ({ name }) {
@@ -10636,13 +10659,25 @@ class PearcordPlatform extends EventEmitter {
}
async toggleReaction (messageId, emoji) {
const span = this.log.time('reaction.toggle', { messageId, emoji: String(emoji || '').slice(0, 16) })
try {
const user = this.identity.user
if (!user) throw new Error('register first')
if (this.mode === 'guild') await this._assertCanParticipate()
const result = await this.messages.toggleReaction(messageId, emoji, user.id)
if (this.mode !== 'dm' && this.guild) this.guild.gossipReaction(result)
this.emit('reaction', result)
span.end({ messageId, emoji: String(emoji || '').slice(0, 16) })
return result
} catch (err) {
this.log.error('reaction.toggle error', {
messageId,
emoji: String(emoji || '').slice(0, 16),
error: err?.message || String(err)
})
span.fail(err)
throw err
}
}
_groupReactions (rows) {
@@ -10662,6 +10697,8 @@ class PearcordPlatform extends EventEmitter {
}
async deleteMessage (messageId) {
const span = this.log.time('message.delete', { messageId })
try {
await this._assertCanModifyMessage(messageId, 'delete')
const channelId = this.activeChannelId
await this.messages.remove(messageId)
@@ -10673,6 +10710,15 @@ class PearcordPlatform extends EventEmitter {
if (this.mode === 'dm' && this.dm) this.dm.gossipMessageDelete(payload)
else if (this.guild) this.guild.gossipMessageDelete(payload)
this.emit('message-delete', payload)
span.end({ messageId })
} catch (err) {
this.log.error('message.delete error', {
messageId,
error: err?.message || String(err)
})
span.fail(err)
throw err
}
}
async channelHistory () {