Discord throwing 500s isn't handled gracefully
Created by: xSke
Summary
When a request to Discord returns a 500 Internal Server Error, it'll often include a JSON body other than the expected value (and sometimes, not even JSON at all). When the library tries to parse this response, it'll fail.
Details
I usually see this with the get webhooks endpoint. Discord will occasionally return a 500 response with the following body:
{"message": "500: Internal Server Error", "code": 0}
The library attempts to parse this as a list of webhook objects, and promptly blows up:
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.IEnumerable`1[DSharpPlus.Entities.DiscordWebhook]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'message', line 1, position 11.
Module "Newtonsoft.Json.Serialization.JsonSerializerInternalReader", in CreateObject
Module "Newtonsoft.Json.Serialization.JsonSerializerInternalReader", in CreateValueInternal
Module "Newtonsoft.Json.Serialization.JsonSerializerInternalReader", in Deserialize
Module "Newtonsoft.Json.JsonSerializer", in DeserializeInternal
Module "Newtonsoft.Json.JsonConvert", in DeserializeObject
Module "Newtonsoft.Json.JsonConvert", in DeserializeObject
Module "DSharpPlus.Net.DiscordApiClient", in GetChannelWebhooksAsync
Module "System.Runtime.ExceptionServices.ExceptionDispatchInfo", in Throw
Module "System.Runtime.CompilerServices.TaskAwaiter", in HandleNonSuccessAndDebuggerNotification
(etc, etc, etc)
A potential fix could be to treat 500 responses similarly to how it already handles 400, 401... and throw an exception type, so the error can be caught and the operation can be retried (either at the library or at the bot end). Ideally this would happen before any JSON parsing happens, as I've seen eg. CloudFlare errors in HTML format be returned a couple times too >.>