private static async Task <(Release latestVersion, Release latestBetaVersion)> GetLatestReleases() { Release latestVersion = null; Release latestBetaVersion = null; try { JArray gitHubInfo = null; await HttpHelper.RetryOnExceptionAsync <Exception> (3, TimeSpan.FromSeconds(2), GITHUB_RELEASES_API_URL, async() => { WebClient client = new WebClient(); client.Headers.Add("user-agent", TVSettings.USER_AGENT); Task <string> response = client.DownloadStringTaskAsync(GITHUB_RELEASES_API_URL); gitHubInfo = JArray.Parse(await response.ConfigureAwait(false)); }).ConfigureAwait(false); if (gitHubInfo is null) { Logger.Error("Failed to contact GitHub to identify new releases - no exception raised"); return(null, null); } foreach (JObject gitHubReleaseJson in gitHubInfo.Children <JObject>()) { try { if (!gitHubReleaseJson["assets"].HasValues) { continue; //we have no files for this release, so ignore } Release testVersion = ParseFromJson(gitHubReleaseJson); (latestBetaVersion, latestVersion) = UpdateLatest(testVersion, latestBetaVersion, latestVersion); } catch (NullReferenceException ex) { Logger.Error("Looks like the JSON payload from GitHub has changed"); Logger.Debug(ex, gitHubReleaseJson.ToString()); } catch (ArgumentOutOfRangeException ex) { Logger.Debug("Generally happens because the release did not have an exe attached"); Logger.Debug(ex, gitHubReleaseJson.ToString()); } } if (latestVersion is null) { Logger.Error("Could not find latest version information from GitHub: {0}", gitHubInfo.ToString()); return(null, latestBetaVersion); } if (latestBetaVersion is null) { Logger.Error("Could not find latest beta version information from GitHub: {0}", gitHubInfo.ToString()); return(latestVersion, null); } } catch (WebException wex) { if (wex.IsUnimportant()) { Logger.Warn($"Failed to contact GitHub to identify new releases {wex.LoggableDetails()}"); } else { Logger.Error($"Failed to contact GitHub to identify new releases {wex.LoggableDetails()}"); } } catch (Exception e) { Logger.Error(e, "Failed to contact GitHub to identify new releases"); } return(latestVersion, latestBetaVersion); }