@@ -109,7 +109,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
109109 private readonly syncStatusContext : IContextKey < string > ;
110110 private readonly authenticationState : IContextKey < string > ;
111111 private readonly conflictsSources : IContextKey < string > ;
112- private readonly conflictsDisposables = new Map < SyncSource , IDisposable > ( ) ;
112+
113113 private readonly badgeDisposable = this . _register ( new MutableDisposable ( ) ) ;
114114 private readonly signInNotificationDisposable = this . _register ( new MutableDisposable ( ) ) ;
115115 private _activeAccount : AuthenticationSession | undefined ;
@@ -149,6 +149,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
149149 this . onDidChangeEnablement ( this . userDataSyncEnablementService . isEnabled ( ) ) ;
150150 this . _register ( Event . debounce ( userDataSyncService . onDidChangeStatus , ( ) => undefined , 500 ) ( ( ) => this . onDidChangeSyncStatus ( this . userDataSyncService . status ) ) ) ;
151151 this . _register ( userDataSyncService . onDidChangeConflicts ( ( ) => this . onDidChangeConflicts ( this . userDataSyncService . conflictsSources ) ) ) ;
152+ this . _register ( userDataSyncService . onSyncErrors ( errors => this . onSyncErrors ( errors ) ) ) ;
152153 this . _register ( this . authTokenService . onTokenFailed ( _ => this . authenticationService . getSessions ( this . userDataSyncStore ! . authenticationProviderId ) ) ) ;
153154 this . _register ( this . userDataSyncEnablementService . onDidChangeEnablement ( enabled => this . onDidChangeEnablement ( enabled ) ) ) ;
154155 this . _register ( this . authenticationService . onDidRegisterAuthenticationProvider ( e => this . onDidRegisterAuthenticationProvider ( e ) ) ) ;
@@ -268,6 +269,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
268269 this . updateBadge ( ) ;
269270 }
270271
272+ private readonly conflictsDisposables = new Map < SyncSource , IDisposable > ( ) ;
271273 private onDidChangeConflicts ( conflicts : SyncSource [ ] ) {
272274 this . updateBadge ( ) ;
273275 if ( conflicts . length ) {
@@ -405,7 +407,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
405407 severity : Severity . Error ,
406408 message : localize ( 'too large' , "Disabled sync {0} because size of the {1} file to sync is larger than {2}. Please open the file and reduce the size and enable sync" , sourceArea , sourceArea , '100kb' ) ,
407409 actions : {
408- primary : [ new Action ( 'open sync file' , localize ( 'open file' , "Show {0} file" , sourceArea ) , undefined , true ,
410+ primary : [ new Action ( 'open sync file' , localize ( 'open file' , "Open {0} file" , sourceArea ) , undefined , true ,
409411 ( ) => error . source === SyncSource . Settings ? this . preferencesService . openGlobalSettings ( true ) : this . preferencesService . openGlobalKeybindingSettings ( true ) ) ]
410412 }
411413 } ) ;
@@ -421,6 +423,47 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
421423 }
422424 }
423425
426+ private readonly invalidContentErrorDisposables = new Map < SyncSource , IDisposable > ( ) ;
427+ private onSyncErrors ( errors : [ SyncSource , UserDataSyncError ] [ ] ) : void {
428+ if ( errors . length ) {
429+ for ( const [ source , error ] of errors ) {
430+ switch ( error . code ) {
431+ case UserDataSyncErrorCode . LocalInvalidContent :
432+ this . handleInvalidContentError ( source ) ;
433+ break ;
434+ default :
435+ const disposable = this . invalidContentErrorDisposables . get ( source ) ;
436+ if ( disposable ) {
437+ disposable . dispose ( ) ;
438+ this . invalidContentErrorDisposables . delete ( source ) ;
439+ }
440+ }
441+ }
442+ } else {
443+ this . invalidContentErrorDisposables . forEach ( disposable => disposable . dispose ( ) ) ;
444+ this . invalidContentErrorDisposables . clear ( ) ;
445+ }
446+ }
447+
448+ private handleInvalidContentError ( source : SyncSource ) : void {
449+ if ( ! this . invalidContentErrorDisposables . has ( source ) ) {
450+ const errorArea = getSyncAreaLabel ( source ) ;
451+ const handle = this . notificationService . notify ( {
452+ severity : Severity . Error ,
453+ message : localize ( 'errorInvalidConfiguration' , "Unable to sync {0} because there are some errors/warnings in the file. Please open the file to correct errors/warnings in it." , errorArea ) ,
454+ actions : {
455+ primary : [ new Action ( 'open sync file' , localize ( 'open file' , "Open {0} file" , errorArea ) , undefined , true ,
456+ ( ) => source === SyncSource . Settings ? this . preferencesService . openGlobalSettings ( true ) : this . preferencesService . openGlobalKeybindingSettings ( true ) ) ]
457+ }
458+ } ) ;
459+ this . invalidContentErrorDisposables . set ( source , toDisposable ( ( ) => {
460+ // close the error warning notification
461+ handle . close ( ) ;
462+ this . invalidContentErrorDisposables . delete ( source ) ;
463+ } ) ) ;
464+ }
465+ }
466+
424467 private async updateBadge ( ) : Promise < void > {
425468 this . badgeDisposable . clear ( ) ;
426469
0 commit comments