Skip to content
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

[FIXED JENKINS-26964] Handle AbortException right #1577

Merged
merged 4 commits into from
May 1, 2015

Conversation

KostyaSha
Copy link
Member

@KostyaSha KostyaSha changed the title WIP [FIXED JENKINS-26964] Handle AbortException right [FIXED JENKINS-26964] Handle AbortException right Feb 21, 2015
e.printStackTrace(listener.error(msg));
if (!(e instanceof AbortException)){
e.printStackTrace(listener.error(msg));
}
LOGGER.log(WARNING, msg, e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why print the stack trace in the log for Aborts?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read code again.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not talking about the build log (listener) but the Jenkins log Logger.log(..) which is called outside the if() statement

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, i can move it to if.

@KostyaSha
Copy link
Member Author

Fixed comment, fixup'ed into one commit.

@ikedam
Copy link
Member

ikedam commented Feb 28, 2015

How about overriding AbortException#printStacktrace()?

  • It can print the message without the stacktrace.
  • No need to handle AbortException everywhere in Jenkins.

@KostyaSha
Copy link
Member Author

@ikedam 👎

@jtnord
Copy link
Member

jtnord commented Mar 1, 2015

👍

@oleg-nenashev
Copy link
Member

@ikedam
I would print AbortException contents to the log in any case. Probably, for code>AbortException stack-traces it makes sense to change the logging level to INFO or FINE in such case

@KostyaSha
Copy link
Member Author

@oleg-nenashev to which log? No need to print stacktrace into listener, this is known and handled exception.

p.getPublishersList().add(new ArtifactArchiver("result.txt", "", false));

FreeStyleBuild b = p.scheduleBuild2(0).get();
assertEquals("Build must fail, because we used FalsePublisher", b.getResult(), Result.FAILURE);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FalsePublisher -> AbortExceptionPublisher

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

@orrc
Copy link
Member

orrc commented Mar 28, 2015

FWIW, the testFreestyleWithFalsePublisher test case fails on my machine.

@KostyaSha
Copy link
Member Author

@orrc interesting, maybe something changed in core. I will try re-trigger PR-build

@KostyaSha KostyaSha closed this Mar 28, 2015
@KostyaSha KostyaSha reopened this Mar 28, 2015
@kohsuke
Copy link
Member

kohsuke commented Apr 29, 2015

👍

@@ -733,8 +734,10 @@ protected final boolean performAllBuildSteps(BuildListener listener, Iterable<?

private void reportError(BuildStep bs, Throwable e, BuildListener listener, boolean phase) {
String msg = "Publisher " + bs.getClass().getName() + " aborted due to exception";
e.printStackTrace(listener.error(msg));
LOGGER.log(WARNING, msg, e);
if (!(e instanceof AbortException)){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is an AbortException, is the message being printed somewhere else already? It needs to be.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The equivalent pattern in the past (of returning false from the perform() method) left no message, so the patch is consistent with that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks also weird for me. Will double-check

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The equivalent pattern in the past (of returning false from the perform() method) left no message

Sure, but then the plugin author was deciding to leave no message (or more likely to print one to a BuildListener earlier). If they decided to throw AbortException, they supplied a message, so we should use it.

@daniel-beck
Copy link
Member

👍

assertEquals("Build must fail, because we used FalsePublisher", b.getResult(), Result.FAILURE);
File file = new File(b.getArtifactsDir(), "result.txt");
assertTrue("ArtifactArchiver is executed even prior publisher fails.", file.exists());
assertTrue("Second publisher must see FAILURE status", FileUtils.readFileToString(file).equals(Result.FAILURE.toString()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I would expect to see the detail message from the AbortException in the log.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also be able to

j.assertBuildStatusNotContains("\tat ", b);

to prove that we suppressed the stack trace.

@kohsuke
Copy link
Member

kohsuke commented Apr 29, 2015

Tests do pass for me.

@Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
FilePath file = build.getWorkspace().child(fileName);
file.write(build.getResult().toString(), Charset.defaultCharset().name());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine, though it would be slightly more concise to just print the result in a specially-formatted message to the listener. Then you can use JenkinsRule.assertBuildLogContains.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

…though perhaps not, since you seem to be assuming that a following ArtifactArchiver will see it, too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interaction with files is not ideal, but it works very well. buildlog can be screwed or has something wrong. File is strict.

@jglick
Copy link
Member

jglick commented Apr 29, 2015

Reviewed. I would be 👍 if AbortException.message were printed. All else is minor, mostly suggestions for strengthening the tests.

@KostyaSha
Copy link
Member Author

Thanks for super review :) I will fix comments

- Print publisher display name instead of class, so user can understand what publisher in UI was used and failed.
- Setter for artifact archiver shows how it handle status
- Minor typos
- Added test for stacktraces in build log
} catch (LinkageError e) {
reportError(bs, e, listener, phase);
r = false;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

performAllBuildSteps is ignored in most calls, but i think this should add consistency for failed execution

@KostyaSha
Copy link
Member Author

Also rebased and noted 😅
I can wrote more tests but i have no ideas what else can be tested.

@@ -723,21 +725,33 @@ protected final boolean performAllBuildSteps(BuildListener listener, Iterable<?
try {
if (!perform(bs,listener)) {
LOGGER.log(Level.FINE, "{0} : {1} failed", new Object[] {AbstractBuild.this, bs});
setResult(Result.FAILURE);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this not need to be conditional on phase, like it is in reportError?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting question.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to have consistency.

- Typo
- Print error combined
- Set result only when phase like in other code parts.
- Test for expected error message in log
@jglick jglick self-assigned this May 1, 2015
@jglick
Copy link
Member

jglick commented May 1, 2015

The last PR build failed randomly (timeout after the notorious Credentials-related errors I can never track down), so submitted for validated merge rather than merging immediately.

@jglick jglick merged commit 161a009 into jenkinsci:master May 1, 2015
jglick added a commit that referenced this pull request May 1, 2015
String msg = "Publisher " + bs.getClass().getName() + " aborted due to exception";
e.printStackTrace(listener.error(msg));
LOGGER.log(WARNING, msg, e);
final String publisher = ((Publisher) bs).getDescriptor().getDisplayName();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note, IDE or static analysing tools didn't highlight this code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
8 participants