@@ -94,6 +94,9 @@ public Collection<StashPullRequestResponseValue> getTargetPullRequests() {
9494    List <StashPullRequestResponseValue > targetPullRequests  =
9595        new  ArrayList <StashPullRequestResponseValue >();
9696
97+     // Fetch "OPEN" pull requests from the server. Failure to get the list will 
98+     // prevent builds from being scheduled. However, the call will be retried 
99+     // during the next cycle, as determined by the cron settings. 
97100    List <StashPullRequestResponseValue > pullRequests ;
98101    try  {
99102      pullRequests  = client .getPullRequests ();
@@ -110,7 +113,15 @@ public Collection<StashPullRequestResponseValue> getTargetPullRequests() {
110113    return  targetPullRequests ;
111114  }
112115
113-   public  String  postBuildStartCommentTo (StashPullRequestResponseValue  pullRequest ) {
116+   /** 
117+    * Post "BuildStarted" comment to Bitbucket Server 
118+    * 
119+    * @param pullRequest pull request 
120+    * @return comment ID 
121+    * @throws StashApiException if posting the comment fails 
122+    */ 
123+   public  String  postBuildStartCommentTo (StashPullRequestResponseValue  pullRequest )
124+       throws  StashApiException  {
114125    String  sourceCommit  = pullRequest .getFromRef ().getLatestCommit ();
115126    String  destinationCommit  = pullRequest .getToRef ().getLatestCommit ();
116127    String  comment  =
@@ -269,6 +280,9 @@ public void addFutureBuildTasks(Collection<StashPullRequestResponseValue> pullRe
269280    for  (StashPullRequestResponseValue  pullRequest  : pullRequests ) {
270281      Map <String , String > additionalParameters ;
271282
283+       // Get parameter values for the build from the pull request comments. 
284+       // Failure to do so causes the build to be skipped, as we would not run 
285+       // the build with incorrect parameters. 
272286      try  {
273287        additionalParameters  = getAdditionalParameters (pullRequest );
274288      } catch  (StashApiException  e ) {
@@ -281,6 +295,8 @@ public void addFutureBuildTasks(Collection<StashPullRequestResponseValue> pullRe
281295        continue ;
282296      }
283297
298+       // Delete comments about previous build results, if that option is 
299+       // enabled. Run the build even if those comments cannot be deleted. 
284300      if  (trigger .getDeletePreviousBuildFinishComments ()) {
285301        try  {
286302          deletePreviousBuildFinishedComments (pullRequest );
@@ -294,7 +310,25 @@ public void addFutureBuildTasks(Collection<StashPullRequestResponseValue> pullRe
294310        }
295311      }
296312
297-       String  commentId  = postBuildStartCommentTo (pullRequest );
313+       // Post a comment indicating the build start. Strictly speaking, we are 
314+       // just adding the build to the queue, it will start after the quiet time 
315+       // expires and there are executors available. Failure to post the comment 
316+       // prevents the build for safety reasons. If the plugin cannot post this 
317+       // comment, chances are it won't be able to post the build results, which 
318+       // would trigger the build again and again, wasting Jenkins resources. 
319+       String  commentId ;
320+       try  {
321+         commentId  = postBuildStartCommentTo (pullRequest );
322+       } catch  (StashApiException  e ) {
323+         logger .log (
324+             Level .INFO ,
325+             format (
326+                 "%s: cannot post Build Start comment for pull request %s, not building" ,
327+                 job .getName (), pullRequest .getId ()),
328+             e );
329+         continue ;
330+       }
331+ 
298332      StashCause  cause  =
299333          new  StashCause (
300334              trigger .getStashHost (),
@@ -315,7 +349,15 @@ public void addFutureBuildTasks(Collection<StashPullRequestResponseValue> pullRe
315349    }
316350  }
317351
318-   public  void  deletePullRequestComment (String  pullRequestId , String  commentId ) {
352+   /** 
353+    * Deletes pull request comment from Bitbucket Server 
354+    * 
355+    * @param pullRequestId pull request ID 
356+    * @param commentId comment to be deleted 
357+    * @throws StashApiException if deleting the comment fails 
358+    */ 
359+   public  void  deletePullRequestComment (String  pullRequestId , String  commentId )
360+       throws  StashApiException  {
319361    this .client .deletePullRequestComment (pullRequestId , commentId );
320362  }
321363
@@ -359,14 +401,41 @@ public void postFinishedComment(
359401
360402    comment  = comment .concat (additionalComment );
361403
362-     this .client .postPullRequestComment (pullRequestId , comment );
404+     // Post the "Build Finished" comment. Failure to post it can lead to 
405+     // scheduling another build for the pull request unnecessarily. 
406+     try  {
407+       this .client .postPullRequestComment (pullRequestId , comment );
408+     } catch  (StashApiException  e ) {
409+       logger .log (
410+           Level .WARNING ,
411+           format (
412+               "%s: cannot post Build Finished comment for pull request %s" ,
413+               job .getDisplayName (), pullRequestId ),
414+           e );
415+     }
363416  }
364417
365-   public  boolean  mergePullRequest (String  pullRequestId , String  version ) {
418+   /** 
419+    * Instructs Bitbucket Server to merge pull request 
420+    * 
421+    * @param pullRequestId pull request ID 
422+    * @param version pull request version 
423+    * @return true if the merge succeeds, false if the server reports an error 
424+    * @throws StashApiException if cannot communicate to the server 
425+    */ 
426+   public  boolean  mergePullRequest (String  pullRequestId , String  version ) throws  StashApiException  {
366427    return  this .client .mergePullRequest (pullRequestId , version );
367428  }
368429
369-   private  boolean  isPullRequestMergeable (StashPullRequestResponseValue  pullRequest ) {
430+   /** 
431+    * Inquiries Bitbucket Server whether the pull request can be merged 
432+    * 
433+    * @param pullRequest pull request 
434+    * @return true if the merge is allowed, false otherwise 
435+    * @throws StashApiException if cannot communicate to the server 
436+    */ 
437+   private  boolean  isPullRequestMergeable (StashPullRequestResponseValue  pullRequest )
438+       throws  StashApiException  {
370439    if  (trigger .getCheckMergeable ()
371440        || trigger .getCheckNotConflicted ()
372441        || trigger .getCheckProbeMergeStatus ()) {
@@ -454,8 +523,21 @@ private boolean isBuildTarget(StashPullRequestResponseValue pullRequest) {
454523      return  false ;
455524    }
456525
457-     if  (!isPullRequestMergeable (pullRequest )) {
458-       logger .info ("Skipping PR: "  + pullRequest .getId () + " as cannot be merged" );
526+     // Check whether the pull request can be merged and whether it's in the 
527+     // "conflicted" state. If that information cannot be retrieved, don't build 
528+     // the pull request in this cycle. 
529+     try  {
530+       if  (!isPullRequestMergeable (pullRequest )) {
531+         logger .info ("Skipping PR: "  + pullRequest .getId () + " as cannot be merged" );
532+         return  false ;
533+       }
534+     } catch  (StashApiException  e ) {
535+       logger .log (
536+           Level .INFO ,
537+           format (
538+               "%s: cannot determine if pull request %s can be merged, skipping" ,
539+               job .getDisplayName (), pullRequest .getId ()),
540+           e );
459541      return  false ;
460542    }
461543
@@ -473,6 +555,10 @@ private boolean isBuildTarget(StashPullRequestResponseValue pullRequest) {
473555    String  destinationCommit  = destination .getLatestCommit ();
474556
475557    String  id  = pullRequest .getId ();
558+ 
559+     // Fetch all comments for the pull request. If it fails, don't build the 
560+     // pull request in this cycle, as it cannot be determined if it should be 
561+     // built without checking the comments. 
476562    List <StashPullRequestComment > comments ;
477563    try  {
478564      comments  = client .getPullRequestComments (owner , repositoryName , id );
0 commit comments