Improve handling of bootstrapper connection errors

This commit is contained in:
pizzaboxer 2024-10-29 21:54:35 +00:00
parent ba561a2421
commit bd506ae545
No known key found for this signature in database
GPG Key ID: 59D4A1DBAD0F2BA8
5 changed files with 57 additions and 45 deletions

View File

@ -125,15 +125,14 @@ namespace Bloxstrap
App.Logger.WriteLine(LOG_IDENT, "Connectivity check failed");
App.Logger.WriteException(LOG_IDENT, exception);
string message = Strings.Dialog_Connectivity_Preventing;
string message = Strings.Dialog_Connectivity_BadConnection;
if (exception.GetType() == typeof(AggregateException))
if (exception is AggregateException)
exception = exception.InnerException!;
if (exception.GetType() == typeof(HttpRequestException))
// https://gist.github.com/pizzaboxer/4b58303589ee5b14cc64397460a8f386
if (exception is HttpRequestException && exception.InnerException is null)
message = String.Format(Strings.Dialog_Connectivity_RobloxDown, "[status.roblox.com](https://status.roblox.com)");
else if (exception.GetType() == typeof(TaskCanceledException))
message = Strings.Dialog_Connectivity_TimedOut;
if (_mustUpgrade)
message += $"\n\n{Strings.Dialog_Connectivity_RobloxUpgradeNeeded}\n\n{Strings.Dialog_Connectivity_TryAgainLater}";
@ -252,6 +251,10 @@ namespace Bloxstrap
Dialog?.CloseBootstrapper();
}
/// <summary>
/// Will throw whatever HttpClient can throw
/// </summary>
/// <returns></returns>
private async Task GetLatestVersionInfo()
{
const string LOG_IDENT = "Bootstrapper::GetLatestVersionInfo";
@ -262,7 +265,11 @@ namespace Bloxstrap
using var key = Registry.CurrentUser.CreateSubKey($"SOFTWARE\\ROBLOX Corporation\\Environments\\{AppData.RegistryName}\\Channel");
var match = Regex.Match(App.LaunchSettings.RobloxLaunchArgs, "channel:([a-zA-Z0-9-_]+)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
var match = Regex.Match(
App.LaunchSettings.RobloxLaunchArgs,
"channel:([a-zA-Z0-9-_]+)",
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant
);
if (match.Groups.Count == 2)
{
@ -273,9 +280,12 @@ namespace Bloxstrap
Deployment.Channel = value.ToLowerInvariant();
}
App.Logger.WriteLine(LOG_IDENT, "Got channel as " + (String.IsNullOrEmpty(Deployment.Channel) ? Deployment.DefaultChannel : Deployment.Channel));
if (String.IsNullOrEmpty(Deployment.Channel))
Deployment.Channel = Deployment.DefaultChannel;
if (Deployment.Channel != "production")
App.Logger.WriteLine(LOG_IDENT, $"Got channel as {Deployment.DefaultChannel}");
if (!Deployment.IsDefaultChannel)
App.SendStat("robloxChannel", Deployment.Channel);
ClientVersion clientVersion;
@ -284,14 +294,9 @@ namespace Bloxstrap
{
clientVersion = await Deployment.GetInfo();
}
catch (HttpRequestException ex)
catch (InvalidChannelException ex)
{
if (ex.StatusCode is not HttpStatusCode.Unauthorized
and not HttpStatusCode.Forbidden
and not HttpStatusCode.NotFound)
throw;
App.Logger.WriteLine(LOG_IDENT, $"Changing channel from {Deployment.Channel} to {Deployment.DefaultChannel} because HTTP {(int)ex.StatusCode}");
App.Logger.WriteLine(LOG_IDENT, $"Resetting channel from {Deployment.Channel} because {ex.StatusCode}");
Deployment.Channel = Deployment.DefaultChannel;
clientVersion = await Deployment.GetInfo();
@ -299,7 +304,7 @@ namespace Bloxstrap
if (clientVersion.IsBehindDefaultChannel)
{
App.Logger.WriteLine(LOG_IDENT, $"Changing channel from {Deployment.Channel} to {Deployment.DefaultChannel} because channel is behind production");
App.Logger.WriteLine(LOG_IDENT, $"Resetting channel from {Deployment.Channel} because it's behind production");
Deployment.Channel = Deployment.DefaultChannel;
clientVersion = await Deployment.GetInfo();

View File

@ -0,0 +1,10 @@
namespace Bloxstrap.Exceptions
{
public class InvalidChannelException : Exception
{
public HttpStatusCode? StatusCode;
public InvalidChannelException(HttpStatusCode? statusCode) : base()
=> StatusCode = statusCode;
}
}

View File

@ -838,6 +838,15 @@ namespace Bloxstrap.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to A connection could not be made, which likely indicates a poor internet connection or a firewall block. If your connection is fine, please ensure that your antivirus isn&apos;t blocking Bloxstrap..
/// </summary>
public static string Dialog_Connectivity_BadConnection {
get {
return ResourceManager.GetString("Dialog.Connectivity.BadConnection", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to More information:.
/// </summary>
@ -847,15 +856,6 @@ namespace Bloxstrap.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Something is likely preventing Bloxstrap from connecting to the internet..
/// </summary>
public static string Dialog_Connectivity_Preventing {
get {
return ResourceManager.GetString("Dialog.Connectivity.Preventing", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Roblox may be down right now. See {0} for more information..
/// </summary>
@ -883,15 +883,6 @@ namespace Bloxstrap.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to The connection timed out, which could indicate a poor internet connection or a firewall block..
/// </summary>
public static string Dialog_Connectivity_TimedOut {
get {
return ResourceManager.GetString("Dialog.Connectivity.TimedOut", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Connectivity error.
/// </summary>

View File

@ -123,14 +123,11 @@
<data name="Bootstrapper.ConfirmLaunch" xml:space="preserve">
<value>Roblox is currently running, and launching another instance will close it. Are you sure you want to continue launching?</value>
</data>
<data name="Dialog.Connectivity.Preventing" xml:space="preserve">
<value>Something is likely preventing Bloxstrap from connecting to the internet.</value>
</data>
<data name="Dialog.Connectivity.RobloxDown" xml:space="preserve">
<value>Roblox may be down right now. See {0} for more information.</value>
</data>
<data name="Dialog.Connectivity.TimedOut" xml:space="preserve">
<value>The connection timed out, which could indicate a poor internet connection or a firewall block.</value>
<data name="Dialog.Connectivity.BadConnection" xml:space="preserve">
<value>A connection could not be made, which likely indicates a poor internet connection or a firewall block. If your connection is fine, please ensure that your antivirus isn't blocking Bloxstrap.</value>
</data>
<data name="Bootstrapper.FirstRunUninstall" xml:space="preserve">
<value>You must first install Bloxstrap before uninstalling.</value>

View File

@ -10,10 +10,17 @@
public static string BinaryType = "WindowsPlayer";
public static bool IsDefaultChannel => String.Compare(Channel, DefaultChannel, StringComparison.OrdinalIgnoreCase) == 0;
public static bool IsDefaultChannel => Channel.Equals(DefaultChannel, StringComparison.OrdinalIgnoreCase);
public static string BaseUrl { get; private set; } = null!;
public static readonly List<HttpStatusCode?> BadChannelCodes = new()
{
HttpStatusCode.Unauthorized,
HttpStatusCode.Forbidden,
HttpStatusCode.NotFound
};
private static readonly Dictionary<string, ClientVersion> ClientVersionCache = new();
// a list of roblox deployment locations that we check for, in case one of them don't work
@ -97,7 +104,9 @@
{
if (exceptions.Any())
return exceptions[0];
return new TaskCanceledException("All tasks have been cancelled"); // we can't add TaskCanceledExceptions to the list
// task cancellation exceptions don't get added to the list
return new TaskCanceledException("All connection attempts timed out.");
}
App.Logger.WriteLine(LOG_IDENT, $"Got {BaseUrl} as the optimal base URL");
@ -157,10 +166,10 @@
{
clientVersion = await Http.GetJson<ClientVersion>("https://clientsettingscdn.roblox.com" + path);
}
catch (HttpRequestException)
catch (HttpRequestException httpEx)
when (!isDefaultChannel && BadChannelCodes.Contains(httpEx.StatusCode))
{
// throw up the exception handler chain, as we shouldn't be the one handling it
throw;
throw new InvalidChannelException(httpEx.StatusCode);
}
catch (Exception ex)
{