diff --git a/ArchiSteamFarm/ArchiWebHandler.cs b/ArchiSteamFarm/ArchiWebHandler.cs index e63c6b0ca..cf89c0dd4 100644 --- a/ArchiSteamFarm/ArchiWebHandler.cs +++ b/ArchiSteamFarm/ArchiWebHandler.cs @@ -443,12 +443,40 @@ namespace ArchiSteamFarm { foreach (Steam.TradeOfferSendRequest trade in trades) { data["json_tradeoffer"] = JsonConvert.SerializeObject(trade); - WebBrowser.ObjectResponse? response = await UrlPostToJsonObjectWithSession(SteamCommunityURL, request, data: data, referer: referer).ConfigureAwait(false); + WebBrowser.ObjectResponse? response = null; + + for (byte i = 0; (i < WebBrowser.MaxTries) && (response == null); i++) { + response = await UrlPostToJsonObjectWithSession(SteamCommunityURL, request, data: data, referer: referer, requestOptions: WebBrowser.ERequestOptions.ReturnServerErrors).ConfigureAwait(false); + + if (response == null) { + return (false, mobileTradeOfferIDs); + } + + if (response.StatusCode.IsServerErrorCode()) { + if (string.IsNullOrEmpty(response.Content?.ErrorText)) { + // This is a generic server error without a reason, try again + response = null; + + continue; + } + + // This is actually client error with a reason, so it doesn't make sense to retry + Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, response.Content!.ErrorText)); + + return (false, mobileTradeOfferIDs); + } + } if (response?.Content == null) { return (false, mobileTradeOfferIDs); } + if (response.Content.TradeOfferID == 0) { + Bot.ArchiLogger.LogNullError(nameof(response.Content.TradeOfferID)); + + return (false, mobileTradeOfferIDs); + } + if (response.Content.RequiresMobileConfirmation) { mobileTradeOfferIDs.Add(response.Content.TradeOfferID); } diff --git a/ArchiSteamFarm/Json/Steam.cs b/ArchiSteamFarm/Json/Steam.cs index 9258f8538..de3fcdf13 100644 --- a/ArchiSteamFarm/Json/Steam.cs +++ b/ArchiSteamFarm/Json/Steam.cs @@ -626,12 +626,15 @@ namespace ArchiSteamFarm.Json { [SuppressMessage("ReSharper", "ClassCannotBeInstantiated")] internal sealed class TradeOfferSendResponse { + [JsonProperty(PropertyName = "strError", Required = Required.DisallowNull)] + internal readonly string ErrorText = ""; + [JsonProperty(PropertyName = "needs_mobile_confirmation", Required = Required.DisallowNull)] internal readonly bool RequiresMobileConfirmation; internal ulong TradeOfferID { get; private set; } - [JsonProperty(PropertyName = "tradeofferid", Required = Required.Always)] + [JsonProperty(PropertyName = "tradeofferid", Required = Required.DisallowNull)] private string TradeOfferIDText { set { if (string.IsNullOrEmpty(value)) {