88import { ExtensionProviderService } from '@salesforce/effect-ext-utils' ;
99import type { ComponentSet } from '@salesforce/source-deploy-retrieve' ;
1010import * as Effect from 'effect/Effect' ;
11+ import * as Schema from 'effect/Schema' ;
12+ import * as vscode from 'vscode' ;
1113import { nls } from '../../messages' ;
1214import { retrieveComponentSet } from '../../shared/retrieve/retrieveComponentSet' ;
1315
16+ class SourceTrackingComponentsFailedError extends Schema . TaggedError < SourceTrackingComponentsFailedError > ( ) (
17+ 'SourceTrackingComponentsFailedError' ,
18+ {
19+ message : Schema . String ,
20+ cause : Schema . optional ( Schema . Unknown )
21+ }
22+ ) { }
23+
1424// Type guard function to ensure result has expected shape
1525const isApplyResult = (
1626 value : unknown
@@ -26,8 +36,8 @@ export const projectRetrieveStartCommand = (ignoreConflicts: boolean) =>
2636 yield * Effect . annotateCurrentSpan ( { ignoreConflicts } ) ;
2737
2838 const api = yield * ( yield * ExtensionProviderService ) . getServicesApi ;
29- const [ sourceTrackingService , channelService ] = yield * Effect . all (
30- [ api . services . SourceTrackingService , api . services . ChannelService ] ,
39+ const [ sourceTrackingService , channelService , componentSetService ] = yield * Effect . all (
40+ [ api . services . SourceTrackingService , api . services . ChannelService , api . services . ComponentSetService ] ,
3141 { concurrency : 'unbounded' }
3242 ) ;
3343
@@ -48,26 +58,30 @@ export const projectRetrieveStartCommand = (ignoreConflicts: boolean) =>
4858 const result = yield * Effect . tryPromise ( {
4959 try : ( ) => tracking . maybeApplyRemoteDeletesToLocal ( true ) ,
5060 catch : e =>
51- new Error ( nls . localize ( 'error_source_tracking_components_failed' , e instanceof Error ? e . message : String ( e ) ) )
61+ new SourceTrackingComponentsFailedError ( {
62+ message : nls . localize ( 'error_source_tracking_components_failed' , e instanceof Error ? e . message : String ( e ) ) ,
63+ cause : e
64+ } )
5265 } ) . pipe ( Effect . withSpan ( 'maybeApplyRemoteDeletesToLocal' ) ) ;
5366
5467 if ( ! isApplyResult ( result ) ) {
5568 return yield * Effect . fail (
56- new Error ( nls . localize ( 'error_source_tracking_components_failed' , 'Invalid result from source tracking' ) )
69+ new SourceTrackingComponentsFailedError ( {
70+ message : nls . localize ( 'error_source_tracking_components_failed' , 'Invalid result from source tracking' )
71+ } )
5772 ) ;
5873 }
5974
6075 const componentSet = result . componentSetFromNonDeletes ;
61-
62- const changeCount = componentSet . size ;
76+ const nonEmpty = yield * componentSetService . ensureNonEmptyComponentSet ( componentSet ) ;
6377 yield * channelService . appendToChannel (
64- `Found ${ changeCount } remote change${ changeCount === 1 ? '' : 's' } to retrieve`
78+ `Found ${ nonEmpty . size } remote change${ nonEmpty . size === 1 ? '' : 's' } to retrieve`
6579 ) ;
66-
67- if ( componentSet . size === 0 ) {
68- yield * channelService . appendToChannel ( 'No remote changes to retrieve' ) ;
69- return ;
70- }
71-
72- yield * retrieveComponentSet ( { componentSet , ignoreConflicts : true } ) ;
73- } ) ;
80+ yield * retrieveComponentSet ( { componentSet : nonEmpty , ignoreConflicts : true } ) ;
81+ } ) . pipe (
82+ Effect . catchTag ( 'EmptyComponentSetError' , ( ) =>
83+ Effect . sync ( ( ) => {
84+ void vscode . window . showInformationMessage ( nls . localize ( 'no_remote_changes_to_retrieve' ) ) ;
85+ } )
86+ )
87+ ) ;
0 commit comments