Repository: serenity-rs/serenity (language: rust)

Issue:
feat(http): Http Error Codes as enum?
I searched through the issue tracker for issues linked to the error code field on the ``serenity::http::error::DiscordJsonError`` and couldn't find any, but this feels like an issue that should've come up, so I apologize if it has done so.

The error field feels it can be improved by either being replaced or supplemented by an enum that covers all currently existing error-codes, with (depending on implementation) either a variant or an Option for if the error-code is unknown.

A list from discords official docs is here:

https://github.com/discord/discord-api-docs/blob/main/docs/topics/Opcodes_and_Status_Codes.md

Would this be wanted? I could potentially implement it myself, with instructions of how the maintainers prefer such implementations.


Discussion / hints:
This sounds like something that would be wanted, using the `enum_number` macro we have which will handle the unknown case.

Fix patch:
diff --git a/src/http/error.rs b/src/http/error.rs
index 1c2004a507a..82d62df1f6f 100644
--- a/src/http/error.rs
+++ b/src/http/error.rs
@@ -10,11 +10,246 @@ use url::ParseError as UrlError;
 
 use crate::internal::prelude::*;
 
+enum_number! {
+    #[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
+    #[non_exhaustive]
+    pub enum JsonErrorCode {
+        General = 0,
+
+        // Unknown entity (10xxx)
+        UnknownAccount = 10001,
+        UnknownApplication = 10002,
+        UnknownChannel = 10003,
+        UnknownGuild = 10004,
+        UnknownIntegration = 10005,
+        UnknownInvite = 10006,
+        UnknownMember = 10007,
+        UnknownMessage = 10008,
+        UnknownPermissionOverwrite = 10009,
+        UnknownProvider = 10010,
+        UnknownRole = 10011,
+        UnknownToken = 10012,
+        UnknownUser = 10013,
+        UnknownEmoji = 10014,
+        UnknownWebhook = 10015,
+        UnknownWebhookService = 10016,
+        UnknownSession = 10020,
+        UnknownBan = 10026,
+        UnknownSKU = 10027,
+        UnknownStoreListing = 10028,
+        UnknownEntitlement = 10029,
+        UnknownBuild = 10030,
+        UnknownLobby = 10031,
+        UnknownBranch = 10032,
+        UnknownStoreDirectoryLayout = 10033,
+        UnknownRedistributable = 10036,
+        UnknownGiftCode = 10038,
+        UnknownStream = 10049,
+        UnknownPremiumServerSubscribeCooldown = 10050,
+        UnknownGuildTemplate = 10057,
+        UnknownDiscoverableServerCategory = 10059,
+        UnknownSticker = 10060,
+        UnknownStickerPack = 10061,
+        UnknownInteraction = 10062,
+        UnknownApplicationCommand = 10063,
+        UnknownVoiceState = 10065,
+        UnknownApplicationCommandPermissions = 10066,
+        UnknownStageInstance = 10067,
+        UnknownGuildMemberVerificationForm = 10068,
+        UnknownGuildWelcomeScreen = 10069,
+        UnknownGuildScheduledEvent = 10070,
+        UnknownGuildScheduledEventUser = 10071,
+        UnknownTag = 10087,
+
+        // Hit restriction (20xxx)
+        BotsCannotUseThisEndpoint = 20001,
+        OnlyBotsCanUseThisEndpoint = 20002,
+        ExplicitContentCannotBeSentToRecipient = 20009,
+        NotAuthorizedForAction = 20012,
+        SlowmodeRateLimit = 20016,
+        OnlyOwnerCanPerform = 20018,
+        AnnouncementRateLimit = 20022,
+        UnderMinimumAge = 20024,
+        ChannelWriteRateLimit = 20028,
+        ServerWriteRateLimit = 20029,
+        ForbiddenWordsInName = 20031,
+        GuildPremiumSubscriptionLevelTooLow = 20035,
+
+        // Hit maximum limit (30xxx)
+        MaxGuildsReached = 30001,
+        MaxFriendsReached = 30002,
+        MaxPinsReached = 30003,
+        MaxRecipientsReached = 30004,
+        MaxGuildRolesReached = 30005,
+        MaxWebhooksReached = 30007,
+        MaxEmojisReached = 30008,
+        MaxReactionsReached = 30010,
+        MaxGroupDMsReached = 30011,
+        MaxGuildChannelsReached = 30013,
+        MaxAttachmentsReached = 30015,
+        MaxInvitesReached = 30016,
+        MaxAnimatedEmojisReached = 30018,
+        MaxServerMembersReached = 30019,
+        MaxServerCategoriesReached = 30030,
+        GuildAlreadyHasTemplate = 30031,
+        MaxApplicationCommandsReached = 30032,
+        MaxThreadParticipantsReached = 30033,
+        MaxDailyApplicationCommandCreatesReached = 30034,
+        MaxNonGuildMemberBansExceeded = 30035,
+        MaxBansFetchesReached = 30037,
+        MaxUncompletedGuildScheduledEventsReached = 30038,
+        MaxStickersReached = 30039,
+        MaxPruneRequestsReached = 30040,
+        MaxGuildWidgetSettingsUpdatesReached = 30042,
+        MaxEditsToOldMessagesReached = 30046,
+        MaxPinnedThreadsInForumChannelReached = 30047,
+        MaxTagsInForumChannelReached = 30048,
+        BitrateTooHighForChannelType = 30052,
+        MaxPremiumEmojisReached = 30056,
+        MaxWebhooksPerGuildReached = 30058,
+        MaxChannelPermissionOverwritesReached = 30060,
+        ChannelsTooLargeForGuild = 30061,
+
+        Unauthorized = 40001,
+        AccountVerificationRequired = 40002,
+        DirectMessagesTooFast = 40003,
+        SendMessagesDisabled = 40004,
+        RequestEntityTooLarge = 40005,
+        FeatureTemporarilyDisabled = 40006,
+        UserBannedFromGuild = 40007,
+        ConnectionRevoked = 40012,
+        TargetUserNotConnectedToVoice = 40032,
+        MessageAlreadyCrossposted = 40033,
+        ApplicationCommandNameExists = 40041,
+        ApplicationInteractionFailed = 40043,
+        CannotSendInForumChannel = 40058,
+        InteractionAlreadyAcknowledged = 40060,
+        TagNamesMustBeUnique = 40061,
+        ServiceResourceRateLimited = 40062,
+        NoTagsForNonModerators = 40066,
+        TagRequiredForForumPost = 40067,
+        EntitlementAlreadyGranted = 40074,
+        CloudflareBlockingRequest = 40333,
+
+        MissingAccess = 50001,
+        InvalidAccountType = 50002,
+        CannotExecuteInDMChannel = 50003,
+        GuildWidgetDisabled = 50004,
+        CannotEditOtherUserMessage = 50005,
+        CannotSendEmptyMessage = 50006,
+        CannotSendMessagesToUser = 50007,
+        CannotSendMessagesInNonTextChannel = 50008,
+        ChannelVerificationLevelTooHigh = 50009,
+        OAuth2ApplicationNoBot = 50010,
+        OAuth2ApplicationLimitReached = 50011,
+        InvalidOAuth2State = 50012,
+        LackPermissionsForAction = 50013,
+        InvalidAuthToken = 50014,
+        NoteTooLong = 50015,
+        MessageBulkDeleteCountInvalid = 50016,
+        InvalidMFALevel = 50017,
+        MessageOnlyPinnedToSentChannel = 50019,
+        InvalidInviteCode = 50020,
+        CannotExecuteOnSystemMessage = 50021,
+        CannotExecuteOnChannelType = 50024,
+        InvalidOAuth2AccessToken = 50025,
+        MissingOAuth2Scope = 50026,
+        InvalidWebhookToken = 50027,
+        InvalidRole = 50028,
+        InvalidRecipient = 50033,
+        MessageTooOldToBulkDelete = 50034,
+        InvalidFormBody = 50035,
+        BotNotInGuild = 50036,
+        InvalidActivityAction = 50039,
+        InvalidAPIVersion = 50041,
+        FileTooLarge = 50045,
+        InvalidFileUploaded = 50046,
+        CannotSelfRedeemGift = 50054,
+        InvalidGuild = 50055,
+        InvalidSku = 50057,
+        InvalidRequestOrigin = 50067,
+        InvalidMessageType = 50068,
+        PaymentSourceRequiredForGift = 50070,
+        CannotModifySystemWebhook = 50073,
+        CannotDeleteCommunityGuildChannel = 50074,
+        CannotEditStickersInMessage = 50080,
+        InvalidStickerSent = 50081,
+        OperationOnArchivedThread = 50083,
+        InvalidThreadNotificationSettings = 50084,
+        BeforeValueEarlierThanThreadCreation = 50085,
+        CommunityServerChannelsMustBeText = 50086,
+        EventEntityTypeMismatch = 50091,
+        ServerNotAvailableInLocation = 50095,
+        ServerMonetizationRequired = 50097,
+        MoreBoostsRequired = 50101,
+        InvalidJsonInRequestBody = 50109,
+        OwnerCannotBePendingMember = 50131,
+        OwnershipTransferNotAllowedToBot = 50132,
+        FailedToResizeAsset = 50138,
+        CannotMixPremiumAndNormalEmoji = 50144,
+        UploadedFileNotFound = 50146,
+        VoiceMessagesNoAdditionalContent = 50159,
+        SingleAudioAttachmentRequired = 50160,
+        MetadataRequiredForVoiceMessages = 50161,
+        VoiceMessagesCannotBeEdited = 50162,
+        CannotDeleteGuildSubscriptionIntegration = 50163,
+        CannotSendVoiceMessagesInChannel = 50173,
+        UserAccountMustBeVerified = 50178,
+        NoPermissionForSticker = 50600,
+
+        TwoFactorRequired = 60003,
+        NoUsersWithDiscordTag = 80004,
+        ReactionBlocked = 90001,
+        UserCannotUseBurstReactions = 90002,
+
+        ApplicationNotAvailable = 110001,
+        ApiResourceOverloaded = 130000,
+        StageAlreadyOpen = 150006,
+
+        CannotReplyWithoutPermission = 160002,
+        ThreadAlreadyCreatedForMessage = 160004,
+        ThreadLocked = 160005,
+        MaxActiveThreadsReached = 160006,
+        MaxActiveAnnouncementThreadsReached = 160007,
+
+        InvalidJsonForLottieFile = 170001,
+        LottiesCannotContainRasterizedImages = 170002,
+        StickerMaxFramerateExceeded = 170003,
+        StickerFrameCountExceedsMax = 170004,
+        StickerFrameRateInvalid = 170006,
+        StickerAnimationDurationExceedsMaximum = 170007,
+
+        CannotUpdateFinishedEvent = 180000,
+        FailedToCreateStage = 180002,
+
+        MessageBlockedByAutomaticModeration = 200000,
+        TitleBlockedByAutomaticModeration = 200001,
+        ForumChannelWebhooksMustHaveThreadNameOrId = 220001,
+        ForumChannelWebhooksCannotHaveBothThreadNameAndId = 220002,
+        WebhooksCanOnlyCreateThreadsInForumChannels = 220003,
+        WebhookServicesCannotBeUsedInForumChannels = 220004,
+        MessageBlockedByHarmfulLinksFilter = 240000,
+
+        OnboardingRequirementsNotMet = 350000,
+        BelowOnboardingRequirements = 350001,
+
+        FailedToBanUsers = 500000,
+        PollVotingBlocked = 520000,
+        PollExpired = 520001,
+        InvalidChannelTypeForPollCreation = 520002,
+        CannotEditPollMessage = 520003,
+        CannotUseEmojiIncludedWithPoll = 520004,
+        CannotExpireNonPollMessage = 520006,
+
+        _ => Unknown(u32),
+    }
+}
+
 #[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
 #[non_exhaustive]
 pub struct DiscordJsonError {
     /// The error code.
-    pub code: i32,
+    pub code: JsonErrorCode,
     /// The error message.
     pub message: FixedString,
     /// The full explained errors with their path in the request body.
@@ -56,7 +291,7 @@ impl ErrorResponse {
             status_code: r.status(),
             url: FixedString::from_str_trunc(r.url().as_str()),
             error: r.json().await.unwrap_or_else(|e| DiscordJsonError {
-                code: -1,
+                code: JsonErrorCode::Unknown(1),
                 errors: FixedArray::empty(),
                 message: format!("[Serenity] Could not decode json when receiving error response from discord:, {e}").trunc_into(),
             }),
@@ -252,7 +487,7 @@ mod test {
     #[tokio::test]
     async fn test_error_response_into() {
         let error = DiscordJsonError {
-            code: 43121215,
+            code: JsonErrorCode::Unknown(43121215),
             errors: FixedArray::empty(),
             message: FixedString::from_static_trunc("This is a Ferris error"),
         };


Test patch: