

















@@ -116,6 +116,25 @@ function getDiscordErrorCode(err: unknown) {
116116return undefined;
117117}
118118119+function getDiscordErrorStatus(err: unknown) {
120+if (!err || typeof err !== "object") {
121+return undefined;
122+}
123+const candidate =
124+"status" in err && err.status !== undefined
125+ ? err.status
126+ : "statusCode" in err && err.statusCode !== undefined
127+ ? err.statusCode
128+ : undefined;
129+if (typeof candidate === "number" && Number.isFinite(candidate)) {
130+return candidate;
131+}
132+if (typeof candidate === "string" && /^\d+$/.test(candidate)) {
133+return Number(candidate);
134+}
135+return undefined;
136+}
137+119138async function buildDiscordSendError(
120139err: unknown,
121140ctx: {
@@ -132,24 +151,26 @@ async function buildDiscordSendError(
132151const code = getDiscordErrorCode(err);
133152if (code === DISCORD_CANNOT_DM) {
134153return new DiscordSendError(
135-"discord dm failed: user blocks dms or privacy settings disallow it",
136-{ kind: "dm-blocked" },
154+`discord dm failed: user blocks dms or privacy settings disallow it (code=${code})`,
155+{ kind: "dm-blocked", discordCode: code, status: getDiscordErrorStatus(err) },
137156);
138157}
139158if (code !== DISCORD_MISSING_PERMISSIONS) {
140159return err;
141160}
142161143162let missing: string[] = [];
163+let probedChannelType: number | undefined;
144164try {
145165const permissions = await fetchChannelPermissionsDiscord(ctx.channelId, {
146166rest: ctx.rest,
147167token: ctx.token,
148168cfg: ctx.cfg,
149169});
170+probedChannelType = permissions.channelType;
150171const current = new Set(permissions.permissions);
151172const required = ["ViewChannel", "SendMessages"];
152-if (isThreadChannelType(permissions.channelType)) {
173+if (isThreadChannelType(probedChannelType)) {
153174required.push("SendMessagesInThreads");
154175}
155176if (ctx.hasMedia) {
@@ -160,15 +181,29 @@ async function buildDiscordSendError(
160181/* ignore permission probe errors */
161182}
162183184+const status = getDiscordErrorStatus(err);
185+const apiDetails = [`code=${code}`, status != null ? `status=${status}` : undefined]
186+.filter(Boolean)
187+.join(" ");
188+const probedPermissions = ["ViewChannel", "SendMessages"];
189+if (isThreadChannelType(probedChannelType)) {
190+probedPermissions.push("SendMessagesInThreads");
191+}
192+if (ctx.hasMedia) {
193+probedPermissions.push("AttachFiles");
194+}
195+const probeSummary = probedPermissions.join("/");
163196const missingLabel = missing.length
164- ? `missing permissions in channel ${ctx.channelId}: ${missing.join(", ")}`
165- : `missing permissions in channel ${ctx.channelId}`;
197+ ? `discord missing permissions in channel ${ctx.channelId}: ${missing.join(", ")}`
198+ : `discord missing permissions in channel ${ctx.channelId}; permission probe did not identify missing ${probeSummary}`;
166199return new DiscordSendError(
167-`${missingLabel}. bot might be muted or blocked by role/channel overrides`,
200+`${missingLabel} (${apiDetails}). bot might be blocked by channel/thread overrides, archived thread state, reply target visibility, or app-role position`,
168201{
169202kind: "missing-permissions",
170203channelId: ctx.channelId,
171204missingPermissions: missing,
205+discordCode: code,
206+ status,
172207},
173208);
174209}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。