@@ -39,6 +39,7 @@ public class PullRequestDetailViewModel : PanePageViewModelBase, IPullRequestDet
3939 IReadOnlyList < IPullRequestChangeNode > changedFilesTree ;
4040 IPullRequestCheckoutState checkoutState ;
4141 IPullRequestUpdateState updateState ;
42+ string errorMessage ;
4243 string operationError ;
4344 bool isBusy ;
4445 bool isLoading ;
@@ -236,6 +237,15 @@ public IPullRequestUpdateState UpdateState
236237 private set { this . RaiseAndSetIfChanged ( ref updateState , value ) ; }
237238 }
238239
240+ /// <summary>
241+ /// Gets an error message to display if loading fails.
242+ /// </summary>
243+ public string ErrorMessage
244+ {
245+ get { return errorMessage ; }
246+ private set { this . RaiseAndSetIfChanged ( ref errorMessage , value ) ; }
247+ }
248+
239249 /// <summary>
240250 /// Gets the error message to be displayed in the action area as a result of an error in a
241251 /// git operation.
@@ -298,10 +308,16 @@ public override void Initialize([AllowNull] ViewWithData data)
298308 else
299309 IsBusy = true ;
300310
301- OperationError = null ;
311+ ErrorMessage = OperationError = null ;
302312 modelService . GetPullRequest ( Repository , prNumber )
303313 . TakeLast ( 1 )
304314 . ObserveOn ( RxApp . MainThreadScheduler )
315+ . Catch < IPullRequestModel , Exception > ( ex =>
316+ {
317+ ErrorMessage = ex . Message . Trim ( ) ;
318+ IsLoading = IsBusy = false ;
319+ return Observable . Empty < IPullRequestModel > ( ) ;
320+ } )
305321 . Subscribe ( x => Load ( x ) . Forget ( ) ) ;
306322 }
307323
@@ -312,94 +328,103 @@ public override void Initialize([AllowNull] ViewWithData data)
312328 /// <param name="files">The pull request's changed files.</param>
313329 public async Task Load ( IPullRequestModel pullRequest )
314330 {
315- var firstLoad = ( Model == null ) ;
316- Model = pullRequest ;
317- Session = await sessionManager . GetSession ( pullRequest ) ;
318- Title = Resources . PullRequestNavigationItemText + " #" + pullRequest . Number ;
319-
320- IsFromFork = pullRequestsService . IsPullRequestFromFork ( Repository , Model ) ;
321- SourceBranchDisplayName = GetBranchDisplayName ( IsFromFork , pullRequest . Head ? . Label ) ;
322- TargetBranchDisplayName = GetBranchDisplayName ( IsFromFork , pullRequest . Base . Label ) ;
323- CommentCount = pullRequest . Comments . Count + pullRequest . ReviewComments . Count ;
324- Body = ! string . IsNullOrWhiteSpace ( pullRequest . Body ) ? pullRequest . Body : Resources . NoDescriptionProvidedMarkdown ;
331+ try
332+ {
333+ var firstLoad = ( Model == null ) ;
334+ Model = pullRequest ;
335+ Session = await sessionManager . GetSession ( pullRequest ) ;
336+ Title = Resources . PullRequestNavigationItemText + " #" + pullRequest . Number ;
325337
326- var changes = await pullRequestsService . GetTreeChanges ( Repository , pullRequest ) ;
327- ChangedFilesTree = ( await CreateChangedFilesTree ( pullRequest , changes ) ) . Children . ToList ( ) ;
338+ IsFromFork = pullRequestsService . IsPullRequestFromFork ( Repository , Model ) ;
339+ SourceBranchDisplayName = GetBranchDisplayName ( IsFromFork , pullRequest . Head ? . Label ) ;
340+ TargetBranchDisplayName = GetBranchDisplayName ( IsFromFork , pullRequest . Base . Label ) ;
341+ CommentCount = pullRequest . Comments . Count + pullRequest . ReviewComments . Count ;
342+ Body = ! string . IsNullOrWhiteSpace ( pullRequest . Body ) ? pullRequest . Body : Resources . NoDescriptionProvidedMarkdown ;
328343
329- var localBranches = await pullRequestsService . GetLocalBranches ( Repository , pullRequest ) . ToList ( ) ;
344+ var changes = await pullRequestsService . GetTreeChanges ( Repository , pullRequest ) ;
345+ ChangedFilesTree = ( await CreateChangedFilesTree ( pullRequest , changes ) ) . Children . ToList ( ) ;
330346
331- IsCheckedOut = localBranches . Contains ( Repository . CurrentBranch ) ;
347+ var localBranches = await pullRequestsService . GetLocalBranches ( Repository , pullRequest ) . ToList ( ) ;
332348
333- if ( IsCheckedOut )
334- {
335- var divergence = await pullRequestsService . CalculateHistoryDivergence ( Repository , Model . Number ) ;
336- var pullEnabled = divergence . BehindBy > 0 ;
337- var pushEnabled = divergence . AheadBy > 0 && ! pullEnabled ;
338- string pullToolTip ;
339- string pushToolTip ;
349+ IsCheckedOut = localBranches . Contains ( Repository . CurrentBranch ) ;
340350
341- if ( pullEnabled )
342- {
343- pullToolTip = string . Format (
344- Resources . PullRequestDetailsPullToolTip ,
345- IsFromFork ? Resources . Fork : Resources . Remote ,
346- SourceBranchDisplayName ) ;
347- }
348- else
351+ if ( IsCheckedOut )
349352 {
350- pullToolTip = Resources . NoCommitsToPull ;
351- }
353+ var divergence = await pullRequestsService . CalculateHistoryDivergence ( Repository , Model . Number ) ;
354+ var pullEnabled = divergence . BehindBy > 0 ;
355+ var pushEnabled = divergence . AheadBy > 0 && ! pullEnabled ;
356+ string pullToolTip ;
357+ string pushToolTip ;
352358
353- if ( pushEnabled )
354- {
355- pushToolTip = string . Format (
356- Resources . PullRequestDetailsPushToolTip ,
357- IsFromFork ? Resources . Fork : Resources . Remote ,
358- SourceBranchDisplayName ) ;
359- }
360- else if ( divergence . AheadBy == 0 )
361- {
362- pushToolTip = Resources . NoCommitsToPush ;
359+ if ( pullEnabled )
360+ {
361+ pullToolTip = string . Format (
362+ Resources . PullRequestDetailsPullToolTip ,
363+ IsFromFork ? Resources . Fork : Resources . Remote ,
364+ SourceBranchDisplayName ) ;
365+ }
366+ else
367+ {
368+ pullToolTip = Resources . NoCommitsToPull ;
369+ }
370+
371+ if ( pushEnabled )
372+ {
373+ pushToolTip = string . Format (
374+ Resources . PullRequestDetailsPushToolTip ,
375+ IsFromFork ? Resources . Fork : Resources . Remote ,
376+ SourceBranchDisplayName ) ;
377+ }
378+ else if ( divergence . AheadBy == 0 )
379+ {
380+ pushToolTip = Resources . NoCommitsToPush ;
381+ }
382+ else
383+ {
384+ pushToolTip = Resources . MustPullBeforePush ;
385+ }
386+
387+ UpdateState = new UpdateCommandState ( divergence , pullEnabled , pushEnabled , pullToolTip , pushToolTip ) ;
388+ CheckoutState = null ;
363389 }
364390 else
365391 {
366- pushToolTip = Resources . MustPullBeforePush ;
367- }
392+ var caption = localBranches . Count > 0 ?
393+ string . Format ( Resources . PullRequestDetailsCheckout , localBranches . First ( ) . DisplayName ) :
394+ string . Format ( Resources . PullRequestDetailsCheckoutTo , await pullRequestsService . GetDefaultLocalBranchName ( Repository , Model . Number , Model . Title ) ) ;
395+ var clean = await pullRequestsService . IsWorkingDirectoryClean ( Repository ) ;
396+ string disabled = null ;
368397
369- UpdateState = new UpdateCommandState ( divergence , pullEnabled , pushEnabled , pullToolTip , pushToolTip ) ;
370- CheckoutState = null ;
371- }
372- else
373- {
374- var caption = localBranches . Count > 0 ?
375- string . Format ( Resources . PullRequestDetailsCheckout , localBranches . First ( ) . DisplayName ) :
376- string . Format ( Resources . PullRequestDetailsCheckoutTo , await pullRequestsService . GetDefaultLocalBranchName ( Repository , Model . Number , Model . Title ) ) ;
377- var clean = await pullRequestsService . IsWorkingDirectoryClean ( Repository ) ;
378- string disabled = null ;
398+ if ( pullRequest . Head == null || ! pullRequest . Head . RepositoryCloneUrl . IsValidUri )
399+ {
400+ disabled = Resources . SourceRepositoryNoLongerAvailable ;
401+ }
402+ else if ( ! clean )
403+ {
404+ disabled = Resources . WorkingDirectoryHasUncommittedCHanges ;
405+ }
379406
380- if ( pullRequest . Head == null || ! pullRequest . Head . RepositoryCloneUrl . IsValidUri )
381- {
382- disabled = Resources . SourceRepositoryNoLongerAvailable ;
407+ CheckoutState = new CheckoutCommandState ( caption , disabled ) ;
408+ UpdateState = null ;
383409 }
384- else if ( ! clean )
410+
411+ if ( firstLoad )
385412 {
386- disabled = Resources . WorkingDirectoryHasUncommittedCHanges ;
413+ usageTracker . IncrementPullRequestOpened ( ) . Forget ( ) ;
387414 }
388415
389- CheckoutState = new CheckoutCommandState ( caption , disabled ) ;
390- UpdateState = null ;
416+ if ( ! isInCheckout )
417+ {
418+ pullRequestsService . RemoveUnusedRemotes ( Repository ) . Subscribe ( _ => { } ) ;
419+ }
391420 }
392-
393- IsLoading = IsBusy = false ;
394-
395- if ( firstLoad )
421+ catch ( Exception ex )
396422 {
397- usageTracker . IncrementPullRequestOpened ( ) . Forget ( ) ;
423+ ErrorMessage = ex . Message . Trim ( ) ;
398424 }
399-
400- if ( ! isInCheckout )
425+ finally
401426 {
402- pullRequestsService . RemoveUnusedRemotes ( Repository ) . Subscribe ( _ => { } ) ;
427+ IsLoading = IsBusy = false ;
403428 }
404429 }
405430
0 commit comments