Skip to content

Commit b310e41

Browse files
committed
Handle EDSM and Spansh data fetch errors more gracefully.
Resolves #2768.
1 parent 45b0366 commit b310e41

File tree

9 files changed

+91
-35
lines changed

9 files changed

+91
-35
lines changed

EDSMResponder/ConfigurationWindow.xaml.cs

Lines changed: 71 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ private void updateEdsmConfiguration()
6060
/// <summary>
6161
/// Obtain the EDSM log and sync it with the local datastore
6262
/// </summary>
63-
private void edsmObtainLogClicked(object sender, RoutedEventArgs e)
63+
private async void edsmObtainLogClicked(object sender, RoutedEventArgs e)
6464
{
6565
try
6666
{
6767
var starMapConfiguration = ConfigService.Instance.edsmConfiguration;
6868

69-
if ( string.IsNullOrEmpty( starMapConfiguration.apiKey ) )
69+
if (string.IsNullOrEmpty(starMapConfiguration.apiKey))
7070
{
7171
edsmFetchLogsButton.IsEnabled = false;
7272
edsmFetchLogsButton.Content = Properties.EDSMResources.log_button_empty_api_key;
@@ -78,42 +78,89 @@ private void edsmObtainLogClicked(object sender, RoutedEventArgs e)
7878

7979
var progress = new Progress<string>(s => edsmFetchLogsButton.Content = s);
8080
var edsmService = new StarMapService(null, true);
81-
Task.Factory.StartNew( () => obtainEdsmLogsAsync( edsmService, progress ), TaskCreationOptions.LongRunning );
8281

82+
// Run the async worker on a background thread and await it so exceptions propagate to this handler.
83+
var worker = Task.Factory
84+
.StartNew(async () => await obtainEdsmLogsAsync(edsmService, progress).ConfigureAwait(false), TaskCreationOptions.LongRunning)
85+
.Unwrap();
86+
87+
await worker.ConfigureAwait(true);
88+
89+
// Only update last sync time if the background work completed successfully.
8390
starMapConfiguration.lastFlightLogSync = DateTime.UtcNow;
8491
ConfigService.Instance.edsmConfiguration = starMapConfiguration;
92+
93+
// Show success state (Progress may have already set this)
94+
edsmFetchLogsButton.Content = Properties.EDSMResources.log_button_fetched;
8595
}
86-
catch ( OperationCanceledException )
96+
catch (OperationCanceledException)
8797
{
8898
// Operation was cancelled, nothing to do here
99+
edsmFetchLogsButton.Content = Properties.EDSMResources.log_button;
100+
Logging.Info("EDSM log fetch cancelled by user.");
101+
}
102+
catch (Exception ex)
103+
{
104+
// Ensure unexpected exceptions are surfaced to the user
105+
var message = Properties.EDSMResources.log_button_error_received + ex.Message;
106+
edsmFetchLogsButton.Content = message;
107+
}
108+
finally
109+
{
110+
// Restore button state on the UI thread after a short delay
111+
await Task.Delay( TimeSpan.FromSeconds( 15 ) ).ConfigureAwait( true );
112+
edsmFetchLogsButton.IsEnabled = true;
113+
edsmFetchLogsButton.Content = string.IsNullOrEmpty( edsmApiKeyTextBox.Text )
114+
? Properties.EDSMResources.log_button_empty_api_key
115+
: Properties.EDSMResources.log_button;
116+
Logging.Info( "EDSM log fetch completed." );
89117
}
90118
}
91119

92120
private static async Task obtainEdsmLogsAsync(StarMapService edsmService, IProgress<string> progress)
93121
{
94-
if (edsmService != null)
122+
if (edsmService == null)
95123
{
96-
try
97-
{
98-
var flightLogs = await edsmService.getStarMapLogAsync().ConfigureAwait(false);
99-
var comments = await edsmService.getStarMapCommentsAsync().ConfigureAwait(false);
100-
var total = flightLogs.Count;
101-
var i = 0;
102-
103-
while (i < total)
104-
{
105-
var batchSize = Math.Min(total, StarMapService.syncBatchSize);
106-
await EDDI.Instance.DataProvider.SyncEdsmLogBatchAsync(flightLogs.Skip(i).Take(batchSize).ToList(), comments).ConfigureAwait(false);
107-
i += batchSize;
108-
progress.Report($"{Properties.EDSMResources.log_button_fetching_progress} {i}/{total}");
109-
}
110-
progress.Report(Properties.EDSMResources.log_button_fetched);
111-
}
112-
catch (EDSMException edsme)
124+
return;
125+
}
126+
127+
try
128+
{
129+
var flightLogs = await edsmService.getStarMapLogAsync().ConfigureAwait(false);
130+
var comments = await edsmService.getStarMapCommentsAsync().ConfigureAwait(false);
131+
var total = flightLogs.Count;
132+
var i = 0;
133+
134+
while (i < total)
113135
{
114-
progress.Report(Properties.EDSMResources.log_button_error_received + edsme.Message);
115-
Logging.Warn(Properties.EDSMResources.log_button_error_received + edsme.Message, edsme);
136+
var batchSize = Math.Min(total, StarMapService.syncBatchSize);
137+
await EDDI.Instance.DataProvider.SyncEdsmLogBatchAsync(flightLogs.Skip(i).Take(batchSize).ToList(), comments).ConfigureAwait(false);
138+
i += batchSize;
139+
progress.Report($"{Properties.EDSMResources.log_button_fetching_progress} {i}/{total}");
116140
}
141+
142+
progress.Report(Properties.EDSMResources.log_button_fetched);
143+
}
144+
catch (EDSMException edsme)
145+
{
146+
// Expected EDSM-specific errors are reported to the UI and logged.
147+
progress.Report(Properties.EDSMResources.log_button_error_received + edsme.Message);
148+
Logging.Warn(Properties.EDSMResources.log_button_error_received + edsme.Message, edsme);
149+
// Re-throw so caller can observe and handle as well if desired.
150+
throw;
151+
}
152+
catch (OperationCanceledException)
153+
{
154+
progress.Report(Properties.EDSMResources.log_button_error_received + " " + "Operation cancelled.");
155+
Logging.Info("EDSM log fetch cancelled.");
156+
throw;
157+
}
158+
catch (Exception ex)
159+
{
160+
// Unexpected exceptions: report to UI, log and rethrow so caller can react.
161+
progress.Report(Properties.EDSMResources.log_button_error_received + ex.Message);
162+
Logging.Warn(Properties.EDSMResources.log_button_error_received + ex.Message, ex);
163+
throw;
117164
}
118165
}
119166
}

EddiSpanshService/CarrierRouter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public async Task<NavWaypointCollection> GetCarrierRouteAsync(string currentSyst
6161
}
6262
catch ( HttpRequestException he )
6363
{
64-
Logging.Error( he.Message, he );
64+
Logging.Warn( he.Message, he );
6565
}
6666

6767
return null;

EddiSpanshService/GalaxyPlotter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public async Task<NavWaypointCollection> GetGalaxyRouteAsync (string currentSyst
6464
}
6565
catch ( HttpRequestException he )
6666
{
67-
Logging.Error( he.Message, he );
67+
Logging.Warn( he.Message, he );
6868
}
6969

7070
return null;

EddiSpanshService/SpanshDumpSystem.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System;
44
using System.Collections.Generic;
55
using System.Linq;
6+
using System.Net;
67
using System.Net.Http;
78
using System.Threading;
89
using System.Threading.Tasks;
@@ -17,10 +18,11 @@ public async Task<StarSystem> GetStarSystemAsync ( ulong systemAddress, bool sho
1718
{
1819
if ( systemAddress == 0 ) { return null; }
1920

21+
HttpResponseMessage clientResponse = null;
2022
try
2123
{
2224
var requestUri = $"dump/{systemAddress}";
23-
var clientResponse = await spanshHttpClient.GetAsync( requestUri, cancellationToken ).ConfigureAwait(false);
25+
clientResponse = await spanshHttpClient.GetAsync( requestUri, cancellationToken ).ConfigureAwait(false);
2426
clientResponse.EnsureSuccessStatusCode();
2527
var responseJson = await clientResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
2628

@@ -35,7 +37,7 @@ public async Task<StarSystem> GetStarSystemAsync ( ulong systemAddress, bool sho
3537
var jResponse = JToken.Parse( responseJson );
3638
if ( jResponse.Contains( "error" ) )
3739
{
38-
Logging.Debug( "Spansh responded with: " + jResponse[ "error" ] );
40+
Logging.Debug( "Spansh API responded with: " + jResponse[ "error" ] );
3941
}
4042
else
4143
{
@@ -44,12 +46,19 @@ public async Task<StarSystem> GetStarSystemAsync ( ulong systemAddress, bool sho
4446
}
4547
catch ( Exception e )
4648
{
47-
Logging.Error( "Failed to parse Spansh response", e );
49+
Logging.Error( "Failed to parse Spansh API response", e );
4850
}
4951
}
5052
catch ( HttpRequestException he )
5153
{
52-
Logging.Error( he.Message, he );
54+
if ( clientResponse?.StatusCode == HttpStatusCode.NotFound )
55+
{
56+
Logging.Warn( $"Spansh API has no record corresponding to System Address [ {systemAddress} ]" );
57+
}
58+
else
59+
{
60+
Logging.Warn( he.Message, he );
61+
}
5362
}
5463

5564
return null;

EddiSpanshService/SpanshQuery.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public async Task<JToken> QueryAsync ( QueryGroup queryGroup, [ NotNull ] Dictio
7070
}
7171
else
7272
{
73-
Logging.Error( he.Message, he );
73+
Logging.Warn( he.Message, he );
7474
}
7575
}
7676
}

EddiSpanshService/SpanshQuerySystemName.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public async Task<List<NavWaypoint>> GetWaypointsBySystemNameAsync (string parti
4848
}
4949
catch ( HttpRequestException he )
5050
{
51-
Logging.Error( he.Message, he );
51+
Logging.Warn( he.Message, he );
5252
return null;
5353
}
5454

EddiSpanshService/SpanshQuickStation.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public async Task<NavWaypoint> GetQuickStationAsync ( long marketId, Cancellatio
5050
}
5151
catch ( HttpRequestException he )
5252
{
53-
Logging.Error( he.Message, he );
53+
Logging.Warn( he.Message, he );
5454
}
5555

5656
return null;

EddiSpanshService/SpanshQuickSystem.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public async Task<StarSystem> GetQuickStarSystemAsync( ulong systemAddress, Canc
5050
}
5151
catch ( HttpRequestException he )
5252
{
53-
Logging.Error( he.Message, he );
53+
Logging.Warn( he.Message, he );
5454
return null;
5555
}
5656

EddiSpanshService/SpanshTypeAhead.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public async Task<List<string>> GetTypeAheadSystemNamesAsync ( string partialSys
3434
}
3535
catch ( HttpRequestException he )
3636
{
37-
Logging.Error( he.Message, he );
37+
Logging.Warn( he.Message, he );
3838
return null;
3939
}
4040
}

0 commit comments

Comments
 (0)