mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-27 07:58:45 -07:00
launcher: friendly errors + Retry / Get help buttons
Raw exception messages ("Access is denied", HttpRequestException
stack traces) gave the user nothing to do. The flow now translates
the common failures into plain language and offers a one-click
retry that re-runs the host/join flow from the top:
- ErrorTranslator handles HttpRequestException (network down),
TaskCanceledException (timeout), SocketException (firewall),
UnauthorizedAccessException + IOException "in use" (Rec Room
open), missing folder / files (re-pick install), cloudflared
download truncation (suggests LAN mode), port 5005 already bound
- Patcher log output goes through TranslateMessage which catches
the same "access denied" / missing files cases
- HostStepsPanel / JoinStepsPanel gain a Retry + "Get help" row
below the steps; visible only on failure
- "Get help" opens README.md#troubleshooting on GitHub
- Stop / new run hides the retry row so a fresh start is clean
This commit is contained in:
+45
-11
@@ -288,6 +288,7 @@ public partial class MainWindow : Window
|
||||
HostStatusText.Text = "";
|
||||
|
||||
StartupStep? activeStep = null;
|
||||
HostRetryPanel.Visibility = Visibility.Collapsed;
|
||||
try
|
||||
{
|
||||
activeStep = StartStep(_hostSteps, 0);
|
||||
@@ -331,7 +332,8 @@ public partial class MainWindow : Window
|
||||
_state.PhotonAppId, _state.PhotonVoiceAppId, _state.PhotonRegion, _hostApex);
|
||||
if (!patch.Ok)
|
||||
{
|
||||
FailStep(activeStep, "Patcher failed: " + Truncate(patch.Log, 300));
|
||||
FailStepWithFriendly(activeStep, ErrorTranslator.TranslateMessage(patch.Log));
|
||||
ShowHostRetry();
|
||||
return;
|
||||
}
|
||||
CompleteStep(activeStep);
|
||||
@@ -356,13 +358,26 @@ public partial class MainWindow : Window
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (activeStep is not null) FailStep(activeStep, ex.Message);
|
||||
else HostStatusText.Text = ex.Message;
|
||||
var friendly = ErrorTranslator.Translate(ex);
|
||||
if (activeStep is not null) FailStepWithFriendly(activeStep, friendly);
|
||||
else HostStatusText.Text = $"{friendly.Title} {friendly.Explanation}";
|
||||
ShowHostRetry();
|
||||
HostStartBtn.IsEnabled = true;
|
||||
HostStopBtn.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowHostRetry()
|
||||
{
|
||||
HostRetryPanel.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
private void OnHostRetry(object sender, RoutedEventArgs e)
|
||||
{
|
||||
HostRetryPanel.Visibility = Visibility.Collapsed;
|
||||
OnHostStart(sender, e);
|
||||
}
|
||||
|
||||
// ── Step helpers ────────────────────────────────────────────────────
|
||||
private static StartupStep StartStep(ObservableCollection<StartupStep> steps, int index)
|
||||
{
|
||||
@@ -377,11 +392,11 @@ public partial class MainWindow : Window
|
||||
step.Progress = null;
|
||||
}
|
||||
|
||||
private static void FailStep(StartupStep step, string detail)
|
||||
private static void FailStepWithFriendly(StartupStep step, FriendlyError err)
|
||||
{
|
||||
step.State = StepState.Failed;
|
||||
step.Progress = null;
|
||||
step.Detail = detail;
|
||||
step.Detail = $"{err.Title} {err.Explanation}";
|
||||
}
|
||||
|
||||
private static void UpdateStepProgress(StartupStep step, DownloadProgress p)
|
||||
@@ -411,6 +426,7 @@ public partial class MainWindow : Window
|
||||
HostStepsList.ItemsSource = null;
|
||||
_hostSteps = null;
|
||||
HostStatusText.Text = "";
|
||||
HostRetryPanel.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
private async Task ShutdownServerAsync()
|
||||
@@ -503,6 +519,7 @@ public partial class MainWindow : Window
|
||||
JoinStepsList.ItemsSource = _joinSteps;
|
||||
JoinStepsPanel.Visibility = Visibility.Visible;
|
||||
JoinStatusText.Text = "";
|
||||
JoinRetryPanel.Visibility = Visibility.Collapsed;
|
||||
|
||||
StartupStep? activeStep = null;
|
||||
try
|
||||
@@ -518,7 +535,8 @@ public partial class MainWindow : Window
|
||||
payload.PhotonAppId, payload.PhotonVoiceAppId, payload.PhotonRegion, payload.Host);
|
||||
if (!patch.Ok)
|
||||
{
|
||||
FailStep(activeStep, "Patcher failed: " + Truncate(patch.Log, 300));
|
||||
FailStepWithFriendly(activeStep, ErrorTranslator.TranslateMessage(patch.Log));
|
||||
JoinRetryPanel.Visibility = Visibility.Visible;
|
||||
return;
|
||||
}
|
||||
CompleteStep(activeStep);
|
||||
@@ -530,12 +548,31 @@ public partial class MainWindow : Window
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (activeStep is not null) FailStep(activeStep, ex.Message);
|
||||
else JoinStatusText.Text = ex.Message;
|
||||
var friendly = ErrorTranslator.Translate(ex);
|
||||
if (activeStep is not null) FailStepWithFriendly(activeStep, friendly);
|
||||
else JoinStatusText.Text = $"{friendly.Title} {friendly.Explanation}";
|
||||
JoinRetryPanel.Visibility = Visibility.Visible;
|
||||
}
|
||||
finally { RefreshJoinReadiness(); }
|
||||
}
|
||||
|
||||
private void OnJoinRetry(object sender, RoutedEventArgs e)
|
||||
{
|
||||
JoinRetryPanel.Visibility = Visibility.Collapsed;
|
||||
OnJoinApply(sender, e);
|
||||
}
|
||||
|
||||
private void OnOpenTroubleshooting(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(new ProcessStartInfo(
|
||||
"https://github.com/DorkSquadRR/DorkNet/blob/main/README.md#troubleshooting")
|
||||
{ UseShellExecute = true });
|
||||
}
|
||||
catch (Exception ex) { ShowError("Couldn't open help: " + ex.Message); }
|
||||
}
|
||||
|
||||
private void OnLaunchRecRoom(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_state.RecRoomPath))
|
||||
@@ -545,9 +582,6 @@ public partial class MainWindow : Window
|
||||
}
|
||||
|
||||
// ── Helpers ─────────────────────────────────────────────────────────
|
||||
private static string Truncate(string s, int max)
|
||||
=> s.Length <= max ? s : s[..max] + "...";
|
||||
|
||||
private void ShowError(string message)
|
||||
=> System.Windows.MessageBox.Show(this, message, "DorkNet",
|
||||
MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
|
||||
Reference in New Issue
Block a user