-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Handle the case when watch.exitCode
may return null
#1366
Handle the case when watch.exitCode
may return null
#1366
Conversation
|
||
CompletableFuture<Integer> exitCodeFuture = watch.exitCode(); | ||
if (exitCodeFuture == null) { | ||
LOGGER.log(Level.FINEST, "Watcher return 'null' instead of exitCode"); |
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.
Maybe we should extend
Lines 563 to 567 in 294ad42
doExec(in, !launcher.isUnix(), printStream, masks, commands); | |
LOGGER.log(Level.INFO, "Created process inside pod: [" + getPodName() + "], container: [" | |
+ containerName + "]" + "[" + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startMethod) + " ms]"); | |
ContainerExecProc proc = new ContainerExecProc(watch, alive, finished, stdin); |
printStream
to proc
so unusual issues can be printed in the build log, rather than the system log where they would only be visible to admins.
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.
Good idea, but I don't know how to do it in a better way. Can I add an additional arg for ContainerExecProc
to pass printStream
and then use it to print a log?
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 think it can be implemented as a separate PR to unblock the issue fix. I can prepare a PR for that.
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.
Can I add an additional arg
That is what I was thinking.
I think it can be implemented as a separate PR
Agreed, it was just an idea.
We have been running this build and it's still throwing NPEs at
|
@jglick Added a commit to address another NullPointerException issue. We will also be testing this build on our Jenkins. |
The updated version is still throwing NPEs, back to the drawing board.
|
src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecProc.java
Outdated
Show resolved
Hide resolved
Updated this PR to the current state we are running. This solves NPEs and improves logging; however, this now shows the original issue, which is with ssh-agent plugin ( |
Addressed, I guess (but please refrain from force-pushing since it makes it much harder for reviewers to track what you changed and when)
pom.xml
Outdated
@@ -3,7 +3,7 @@ | |||
<parent> | |||
<groupId>org.jenkins-ci.plugins</groupId> | |||
<artifactId>plugin</artifactId> | |||
<version>4.61</version> | |||
<version>4.62</version> |
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.
Please, for next time, avoid introducing unrelated changes, as it makes the review work harder and increases the likelihood of merge conflicts.
Version bumps like this are usually handled via automated PRs filed by Dependabot, e.g. #1382
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.
Thanks for the note! Currently rebased to latest upstream and this bump is no longer included with PR.
src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecProc.java
Outdated
Show resolved
Hide resolved
src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecProc.java
Outdated
Show resolved
Hide resolved
Hello, does anyone have a date to include this bug fix? |
After changes introduced in [PR][1] we have frequent error with `NullPointerException`. Based on a [documentation][2] for `watch.exitCode` method it's clear that watch.exitCode() can return null if close is received before the exit code. In such a case, you can handle the null value and provide an appropriate default or error value. ``` java.lang.NullPointerException at org.csanchez.jenkins.plugins.kubernetes.pipeline.ContainerExecProc.join(ContainerExecProc.java:89) at hudson.Proc.joinWithTimeout(Proc.java:174) at com.cloudbees.jenkins.plugins.sshagent.exec.ExecRemoteAgent.stop(ExecRemoteAgent.java:129) ``` Fix for JENKINS-71135 [1]: #1260 [2]: https://github.com/fabric8io/kubernetes-client/blob/8a879128d893627a40d64cf2a9c7d5da2e7f47d2/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/ExecWatch.java#L68-L82
Completable future can be completed exceptionally with NullPointerException, in which case join() would re-throw this exception. Replacing join() with get(), which throws ExecutionException instead, which wraps the original exception. This exception is caught and handled appropriately.
Completable future can be completed exceptionally with NullPointerException, in which case join() would re-throw this exception. Replacing join() with get(), which throws ExecutionException instead, which wraps the original exception. This exception is caught and handled appropriately.
Adding logging of errors in build log for improved visibility.
…/ContainerExecProc.java Co-authored-by: Vincent Latombe <vincent@latombe.net>
…/ContainerExecProc.java Co-authored-by: Vincent Latombe <vincent@latombe.net>
src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecProc.java
Outdated
Show resolved
Hide resolved
return watch.exitCode().join(); | ||
|
||
CompletableFuture<Integer> exitCodeFuture = watch.exitCode(); | ||
Integer exitCode = exitCodeFuture.get(); |
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.
Does this not contradict the PR title, that it is possible exitCodeFuture == null
? Either the code or the PR title is incorrect.
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.
(Docs are ambiguous whether null
refers to CompletableFuture<Integer>
, or the value of the CompletableFuture
.)
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 goal here is to handle all possible outcomes (null exitCode
is handled in this block, null exitCodeFuture
in catchall block, checked ExecutionException
that can be thrown by get()
in catch block).
The PR title refers to the original issue that's causing NPEs on current master when exitCode
is null, but what would you suggest as a better naming/solution here?
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.
null
exitCodeFuture
in catchall block
If you mean in the catch (Exception
block, then yes, but code should never knowingly be catching NullPointerException
; it should check for null. Conversely, if you were relying on arbitrary unknown exceptions, you might as well keep it simple
try {
return watch.exitCode().join();
} catch (Exception x) {
LOGGER.log(Level.FINEST, "Exception occurred while waiting for exit code", x);
return -1;
}
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.
Alright, agreed - how about now?
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.
@jglick could you please re-review?
…/ContainerExecProc.java Co-authored-by: Jesse Glick <jglick@cloudbees.com>
return watch.exitCode().join(); | ||
|
||
CompletableFuture<Integer> exitCodeFuture = watch.exitCode(); | ||
Integer exitCode = exitCodeFuture.get(); |
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.
null
exitCodeFuture
in catchall block
If you mean in the catch (Exception
block, then yes, but code should never knowingly be catching NullPointerException
; it should check for null. Conversely, if you were relying on arbitrary unknown exceptions, you might as well keep it simple
try {
return watch.exitCode().join();
} catch (Exception x) {
LOGGER.log(Level.FINEST, "Exception occurred while waiting for exit code", x);
return -1;
}
src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecProc.java
Outdated
Show resolved
Hide resolved
…/ContainerExecProc.java Co-authored-by: Jesse Glick <jglick@cloudbees.com>
After changes introduced in #1260 we have frequent error with
NullPointerException
. Based on a documentation forwatch.exitCode
method it's clear that watch.exitCode() can return null if close is received before the exit code. In such a case, you can handle the null value and provide an appropriate default or error value.Fix for JENKINS-71135