fix(auto-delete): guard nickname reset on role hierarchy + surface LLM parse errors
- resetOffensiveNickname: skip when target role sits above bot (member.manageable) instead of hammering a doomed setNickname PATCH that Discord rejects with 50013 'Missing Permissions'. Log the Discord error code on failure for clear diagnosis. - llmCaller: include contentPreview (first 200 chars) in the parse- failure warning so non-JSON LLM responses are debuggable.
This commit is contained in:
@@ -74,6 +74,23 @@ export async function resetOffensiveNickname(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const member = await guild.members.fetch(userId);
|
const member = await guild.members.fetch(userId);
|
||||||
|
// Discord rejects setNickname with "Missing Permissions" (code 50013)
|
||||||
|
// whenever the target's top role sits above the bot in the role
|
||||||
|
// hierarchy — even when the bot has MANAGE_NICKNAMES. Guard on
|
||||||
|
// `manageable` (hierarchy-aware) so we skip with a clear reason
|
||||||
|
// instead of hammering a doomed PATCH on every message.
|
||||||
|
if (!member.manageable) {
|
||||||
|
logger.debug(
|
||||||
|
{
|
||||||
|
messageId,
|
||||||
|
guildId,
|
||||||
|
userId,
|
||||||
|
reason: "target role above bot in hierarchy (Discord 50013)",
|
||||||
|
},
|
||||||
|
"Nick reset skipped: member not manageable by bot",
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// setNickname(null) = remove nickname → Discord shows global username
|
// setNickname(null) = remove nickname → Discord shows global username
|
||||||
await member.setNickname(null, "[auto] nickname melanggar aturan server");
|
await member.setNickname(null, "[auto] nickname melanggar aturan server");
|
||||||
recentNicknameResets.set(cooldownKey, Date.now());
|
recentNicknameResets.set(cooldownKey, Date.now());
|
||||||
@@ -83,12 +100,17 @@ export async function resetOffensiveNickname(
|
|||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
const errCode =
|
||||||
|
error instanceof Error && "code" in error
|
||||||
|
? (error as { code?: number | string }).code
|
||||||
|
: undefined;
|
||||||
logger.warn(
|
logger.warn(
|
||||||
{
|
{
|
||||||
messageId,
|
messageId,
|
||||||
guildId,
|
guildId,
|
||||||
userId,
|
userId,
|
||||||
error: error instanceof Error ? error.message : String(error),
|
error: error instanceof Error ? error.message : String(error),
|
||||||
|
code: errCode,
|
||||||
},
|
},
|
||||||
"Nick reset failed",
|
"Nick reset failed",
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ export async function callModerationLLM(
|
|||||||
{
|
{
|
||||||
error: state.lastParseError,
|
error: state.lastParseError,
|
||||||
contentLength: rawContent.length,
|
contentLength: rawContent.length,
|
||||||
|
contentPreview: rawContent.slice(0, 200),
|
||||||
targetIds,
|
targetIds,
|
||||||
model: config.AI_LLM_MODEL,
|
model: config.AI_LLM_MODEL,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user