-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handling error messaging when PR creation fails with Invalid code error #321
Conversation
log.info("error: {}", error); | ||
if (error.startsWith("A pull request already exists")) { | ||
log.info("NOTE: {} New commits may have been added to the pull request.", error); | ||
return 0; | ||
} else if (error.startsWith("No commits between")) { | ||
} else if (error.startsWith("No commits between") || error.startsWith("PR head has invalid code.")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line is longer than 100 characters (found 113).
Codecov Report
@@ Coverage Diff @@
## master #321 +/- ##
============================================
+ Coverage 81.49% 81.55% +0.05%
- Complexity 263 265 +2
============================================
Files 19 19
Lines 935 938 +3
Branches 126 127 +1
============================================
+ Hits 762 765 +3
Misses 142 142
Partials 31 31
|
if (errorJson.get(0).getAsJsonObject().has("message")) { | ||
error = errorJson.get(0).getAsJsonObject().get("message").getAsString(); | ||
} else { | ||
error = "PR head has invalid code."; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does "invalid code" mean? What action should be taken to resolve if any?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message is trying to communicate that the field/keyword called "head" contains invalid data. When i saw this message, I manually deleted the fork and the next run was successful. This change will also do the same - deleted the fork.
log.info("error: {}", error); | ||
if (error.startsWith("A pull request already exists")) { | ||
log.info("NOTE: {} New commits may have been added to the pull request.", error); | ||
return 0; | ||
} else if (error.startsWith("No commits between")) { | ||
} else if (error.startsWith("No commits between") || error.startsWith("PR head has invalid code.")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Repeated error message. Let's make it a constant in this class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but I think we should improve the error message.
if (errorJson.get(0).getAsJsonObject().has("message")) { | ||
error = errorJson.get(0).getAsJsonObject().get("message").getAsString(); | ||
} else { | ||
// This case usually happens when the PR head has invalid data. Deleting the forked repo resolves it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line is longer than 100 characters (found 117).
log.info("error: {}", error); | ||
if (error.startsWith("A pull request already exists")) { | ||
log.info("NOTE: {} New commits may have been added to the pull request.", error); | ||
return 0; | ||
} else if (error.startsWith("No commits between")) { | ||
} else if (error.startsWith("No commits between") || error.startsWith(PR_INVALID_CODE)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line is longer than 100 characters (found 101).
@@ -29,6 +29,7 @@ | |||
public class GitHubUtil { | |||
private static final Logger log = LoggerFactory.getLogger(GitHubUtil.class); | |||
public static final String NO_BRANCH_WARN_FORMAT = "Couldn't find branch `%s` in repo `%s`. Waiting a second..."; | |||
public static final String PR_INVALID_CODE = "The PR head has invalid data."; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still don't think a user or admin will understand this error message. Can we hint at what needs to be done to fix the PR?
@@ -29,6 +29,8 @@ | |||
public class GitHubUtil { | |||
private static final Logger log = LoggerFactory.getLogger(GitHubUtil.class); | |||
public static final String NO_BRANCH_WARN_FORMAT = "Couldn't find branch `%s` in repo `%s`. Waiting a second..."; | |||
public static final String PR_INVALID_CODE = "The PR head has invalid data. This might be because the repository was migrated to another organization." + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line is longer than 100 characters (found 157).
@@ -29,6 +29,8 @@ | |||
public class GitHubUtil { | |||
private static final Logger log = LoggerFactory.getLogger(GitHubUtil.class); | |||
public static final String NO_BRANCH_WARN_FORMAT = "Couldn't find branch `%s` in repo `%s`. Waiting a second..."; | |||
public static final String PR_INVALID_CODE = "The PR head has invalid data. This might be because the repository was migrated to another organization." + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'+' should be on a new line.
Hmm... Are there other scenarios that end up taking this path? My concern is that when you delete a fork, the API will lag by hours and may select a fork that is no longer there. Additionally, I believe this may have an effect on open PRs. |
log.info("error: {}", error); | ||
if (error.startsWith("A pull request already exists")) { | ||
log.info("NOTE: {} New commits may have been added to the pull request.", error); | ||
return 0; | ||
} else if (error.startsWith("No commits between")) { | ||
} else if (error.startsWith("No commits between") || error.startsWith(PR_INVALID_CODE)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create a list of error prefixes and use stream operations
List<String> prefixes = Arrays.asList(PR_INVALID_CODE, "No commits between")
if(prefixes.anyMatch(prefix -> errors.startsWith(prefix))
This way if you add more prefixes the if statement doesn't change.
@@ -108,12 +110,18 @@ public int createPullReq(GHRepository origRepo, String branch, | |||
log.warn("Handling error with pull request creation... {}", e.getMessage()); | |||
JsonElement root = JsonParser.parseString(e.getMessage()); | |||
JsonArray errorJson = root.getAsJsonObject().get("errors").getAsJsonArray(); | |||
String error = errorJson.get(0).getAsJsonObject().get("message").getAsString(); | |||
String error = ""; | |||
if (errorJson.get(0).getAsJsonObject().has("message")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Store the output of errorJson.get(0).getAsJsonObject()
as a local variable. Call has
and get
on that variable. This removes the need to call get(0).getAsJsonObject()
twice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we ignoring other errors if multiple were returned?
error = errorJson.get(0).getAsJsonObject().get("message").getAsString(); | ||
} else { | ||
// This case usually happens when the PR head has invalid data. Deleting the forked repo resolves it. | ||
error = PR_INVALID_CODE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need this else. Just assign String error = PR_INVALID_CODE
at 113.
GHRepository forkRepo = mock(GHRepository.class); | ||
when(forkRepo.getOwnerName()).thenReturn("owner"); | ||
assertEquals(gitHubUtil.createPullReq(origRepo, "branch", forkRepo, "title", "body"), 1); | ||
verify(origRepo, times(1)).createPullRequest(eq("title"), eq("owner:branch"), eq("master"), eq("body")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
times(1) is the default for verify, you can remove the second parameter.
Hmm, in that case we might just want to make sure that we catch the exception by checking if the json field actually exists before accessing it, but not return 1 -> which is what triggers the delete of the fork. |
There are cases when the PR creation fails and the exception message thrown looks like this:
{"message":"Validation Failed","errors":[{"resource":"PullRequest","field":"head","code":"invalid"}],"documentation_url":"https://docs.github.com/enterprise/3.1/rest/reference/pulls#create-a-pull-request"}
In such case, this line will throw a NullPointerException since the JsonArray does not have a field called
message
. Unfortunately, since this error is thrown inside thecatch
block, it is not handled and essentially terminates the process.This PR checks for the existence of this key inside the Json object before trying to get it. If it does not find it there, it assumes that the error was due to the head having invalid code (error message shown above). In such a scenario, the method returns an error code of 1, so that we can proceed to safely deleting the forked repo here