@@ -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 }
0 commit comments