Skip to content

Commit

Permalink
feature: do not catch exceptions occuring inside the plugin (#626)
Browse files Browse the repository at this point in the history
  • Loading branch information
bguerin authored May 2, 2023
1 parent 10f6e41 commit 43b82f2
Showing 13 changed files with 99 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.jenkinsci.plugins.pipeline.maven;

import static java.util.stream.Collectors.joining;

import java.util.List;

import org.jenkinsci.plugins.pipeline.maven.publishers.MavenPipelinePublisherException;

public class MavenPipelineException extends RuntimeException {

private static final long serialVersionUID = 4164091766147994893L;

public MavenPipelineException(Throwable cause) {
super("Exception occured in withMaven pipeline step: " + cause.getMessage(), cause);
}

public MavenPipelineException(List<MavenPipelinePublisherException> publishersExceptions) {
super(publishersExceptions.size() + " exceptions occured within the publishers of the withMaven pipeline step:\n"
+ publishersExceptions.stream().map(e -> {
StringBuilder builder = new StringBuilder("- ");
builder.append(e.getMessage());
if (e.getCause() != null) {
builder.append(": ").append(e.getCause().getMessage());
}
return builder.toString();
}).collect(joining()));
}
}
Original file line number Diff line number Diff line change
@@ -30,6 +30,7 @@
import jenkins.model.InterruptedBuildAction;
import org.apache.commons.lang.StringUtils;
import org.jenkinsci.plugins.pipeline.maven.publishers.JenkinsMavenEventSpyLogsPublisher;
import org.jenkinsci.plugins.pipeline.maven.publishers.MavenPipelinePublisherException;
import org.jenkinsci.plugins.pipeline.maven.util.XmlUtils;
import org.jenkinsci.plugins.workflow.steps.StepContext;
import org.w3c.dom.Element;
@@ -134,6 +135,7 @@ public void processMavenSpyLogs(@NonNull StepContext context, @NonNull FilePath
listener.getLogger().println("[withMaven] Maven Publisher Strategy: " + publisherStrategy.getDescription());
}
List<MavenPublisher> mavenPublishers = publisherStrategy.buildPublishersList(options, listener);
List<MavenPipelinePublisherException> exceptions = new ArrayList<>();
for (MavenPublisher mavenPublisher : mavenPublishers) {
String skipFileName = mavenPublisher.getDescriptor().getSkipFileName();
if (Boolean.TRUE.equals(mavenPublisher.isDisabled())) {
@@ -156,26 +158,37 @@ public void processMavenSpyLogs(@NonNull StepContext context, @NonNull FilePath
TimeUnit.MILLISECONDS.convert(System.nanoTime() - nanosBefore, TimeUnit.NANOSECONDS) + "ms.");
Thread.currentThread().interrupt(); // set interrupt flag
throw e;
} catch (IOException | RuntimeException e) {
} catch (MavenPipelinePublisherException e) {
exceptions.add(e);
} catch (Exception e) {
PrintWriter error = listener.error("[withMaven] WARNING Exception executing Maven reporter '" + mavenPublisher.getDescriptor().getDisplayName() +
"' / " + mavenPublisher.getDescriptor().getId() + "." +
" Please report a bug associated for the component 'pipeline-maven-plugin' at https://issues.jenkins-ci.org ");
e.printStackTrace(error);
exceptions.add(new MavenPipelinePublisherException(mavenPublisher.getDescriptor().getDisplayName(), "", e));
} finally {
durationInMillisPerPublisher.add(new AbstractMap.SimpleImmutableEntry(mavenPublisher.getDescriptor().getDisplayName(), TimeUnit.MILLISECONDS.convert(System.nanoTime() - nanosBeforePublisher, TimeUnit.NANOSECONDS)));
}
}
}
if (!exceptions.isEmpty()) {
throw new MavenPipelineException(exceptions);
}
} catch (MavenPipelineException e) {
throw e;
} catch (SAXException e) {
Run run = context.get(Run.class);
String msg = "";
if (run.getActions(InterruptedBuildAction.class).isEmpty()) {
listener.error("[withMaven] WARNING Exception parsing the logs generated by the Jenkins Maven Event Spy " + mavenSpyLogs + ", ignore file. " +
" Please report a bug associated for the component 'pipeline-maven-plugin' at https://issues.jenkins-ci.org ");
msg = "[withMaven] WARNING Exception parsing the logs generated by the Jenkins Maven Event Spy " + mavenSpyLogs + ", ignore file. " +
" Please report a bug associated for the component 'pipeline-maven-plugin' at https://issues.jenkins-ci.org ";
} else {
// job has been aborted (see InterruptedBuildAction)
listener.error("[withMaven] WARNING logs generated by the Jenkins Maven Event Spy " + mavenSpyLogs + " are invalid, probably due to the interruption of the job, ignore file.");
msg = "[withMaven] WARNING logs generated by the Jenkins Maven Event Spy " + mavenSpyLogs + " are invalid, probably due to the interruption of the job, ignore file.";
}
listener.error(e.toString());
PrintWriter errorWriter = listener.error(msg);
e.printStackTrace(errorWriter);
throw new MavenPipelineException(e);
} catch (InterruptedException e) {
PrintWriter errorWriter = listener.error("[withMaven] Processing of Maven build outputs interrupted after " +
TimeUnit.MILLISECONDS.convert(System.nanoTime() - nanosBefore, TimeUnit.NANOSECONDS) + "ms.");
@@ -188,13 +201,13 @@ public void processMavenSpyLogs(@NonNull StepContext context, @NonNull FilePath
PrintWriter errorWriter = listener.error("[withMaven] WARNING Exception processing the logs generated by the Jenkins Maven Event Spy " + mavenSpyLogs + ", ignore file. " +
" Please report a bug associated for the component 'pipeline-maven-plugin' at https://issues.jenkins-ci.org ");
e.printStackTrace(errorWriter);
throw new MavenPipelineException(e);
} finally {
if (LOGGER.isLoggable(Level.INFO)) {
listener.getLogger().println("[withMaven] Publishers: " +
durationInMillisPerPublisher.stream().filter(entry -> entry.getValue() > 0).
map(entry -> entry.getKey() + ": " + entry.getValue() + " ms").
collect(Collectors.joining(", ")));

}
}
}
Original file line number Diff line number Diff line change
@@ -353,7 +353,7 @@ public void cleanup() {
}
}

protected long getOrCreateBuildPrimaryKey(String jobFullName, int buildNumber) {
protected synchronized long getOrCreateBuildPrimaryKey(String jobFullName, int buildNumber) {
try (Connection cnn = ds.getConnection()) {
cnn.setAutoCommit(false);

Original file line number Diff line number Diff line change
@@ -142,9 +142,9 @@ public void process(@NonNull final StepContext context, @NonNull final Element m
"\" with the following files: " + target.getReportFiles());
HtmlPublisher.publishReports(run, workspace, listener, Collections.singletonList(target), HtmlPublisher.class);
} catch (final Exception e) {
listener.error("[withMaven] concordionPublisher - exception archiving Concordion reports: " + e + ". Failing the build.");
listener.error("[withMaven] concordionPublisher - exception archiving Concordion reports: " + e);
LOGGER.log(Level.WARNING, "Exception processing Concordion reports archiving", e);
run.setResult(Result.FAILURE);
throw new MavenPipelinePublisherException("concordionPublisher", "archiving Concordion reports", e);
}
}

Original file line number Diff line number Diff line change
@@ -235,13 +235,12 @@ public void process(@NonNull StepContext context, @NonNull Element mavenSpyLogsE
findBugsPublisher.perform(run, workspace, launcher, listener);
} catch (Exception e) {
listener.error("[withMaven] findbugsPublisher - exception archiving FindBugs results for Maven artifact " + mavenArtifact.toString() + " generated by " +
pluginInvocation + ": " + e + ". Failing the build.");
pluginInvocation + ": " + e);
LOGGER.log(Level.WARNING, "Exception processing " + XmlUtils.toString(findBugsTestEvent), e);
run.setResult(Result.FAILURE);
throw new MavenPipelinePublisherException("findbugsPublisher",
"archiving FindBugs results for Maven artifact " + mavenArtifact.getId() + " generated by " + pluginInvocation.getId(), e);
}

}

}

/**
Original file line number Diff line number Diff line change
@@ -136,11 +136,13 @@ public void process(@NonNull StepContext context, @NonNull Element mavenSpyLogsE

// FINGERPRINT GENERATED MAVEN ARTIFACT
if (!fingerprintFilesDisabled) {
FingerprintMap fingerprintMap = Jenkins.get().getFingerprintMap();
for (Map.Entry<String, String> artifactToFingerprint : artifactsToFingerPrint.entrySet()) {
String artifactPathInArchiveZone = artifactToFingerprint.getKey();
String artifactMd5 = artifactToFingerprint.getValue();
fingerprintMap.getOrCreate(run, artifactPathInArchiveZone, artifactMd5).addFor(run);
synchronized (this) { // to avoid exceptions when creating folders under Jenkins home
FingerprintMap fingerprintMap = Jenkins.get().getFingerprintMap();
for (Map.Entry<String, String> artifactToFingerprint : artifactsToFingerPrint.entrySet()) {
String artifactPathInArchiveZone = artifactToFingerprint.getKey();
String artifactMd5 = artifactToFingerprint.getValue();
fingerprintMap.getOrCreate(run, artifactPathInArchiveZone, artifactMd5).addFor(run);
}
}

// add action
Original file line number Diff line number Diff line change
@@ -222,11 +222,11 @@ private void executeReporterForOldEvents(StepContext context, TaskListener liste
try {
archiver.perform(run, workspace, launcher, listener, node);
} catch (Exception e) {
listener.error("[withMaven] invokerPublisher - exception archiving Invoker runs for Maven artifact " + mavenArtifact.getId() + " generated by " + pluginInvocation.getId() + ": " + e + ". Failing the build.");
listener.error("[withMaven] invokerPublisher - exception archiving Invoker runs for Maven artifact " + mavenArtifact.getId() + " generated by " + pluginInvocation.getId() + ": " + e);
LOGGER.log(Level.WARNING, "Exception processing " + XmlUtils.toString(testEvent), e);
run.setResult(Result.FAILURE);
throw new MavenPipelinePublisherException("invokerPublisher",
"archiving Invoker runs for Maven artifact " + mavenArtifact.getId() + " generated by " + pluginInvocation.getId(), e);
}

}
}

Original file line number Diff line number Diff line change
@@ -117,9 +117,9 @@ public void process(@NonNull final StepContext context, @NonNull final Element m
generator.perform(run, workspace, launcher, listener);
} catch (final Exception e) {
listener.error(
"[withMaven] jgivenPublisher - exception archiving JGiven reports: " + e + ". Failing the build.");
"[withMaven] jgivenPublisher - exception archiving JGiven reports: " + e);
LOGGER.log(Level.WARNING, "Exception processing JGiven reports archiving", e);
run.setResult(Result.FAILURE);
throw new MavenPipelinePublisherException("jgivenPublisher", "archiving JGiven reports", e);
}
}

Original file line number Diff line number Diff line change
@@ -100,9 +100,9 @@ static void archiveResults(final StepContext context, final JUnitResultArchiver
run.setResult(Result.UNSTABLE);
}
} catch (RuntimeException e) {
listener.error("[withMaven] " + publisherName + " - exception archiving JUnit results " + testResults + ": " + e + ". Failing the build.");
listener.error("[withMaven] " + publisherName + " - exception archiving JUnit results " + testResults + ": " + e);
LOGGER.log(Level.WARNING, "Exception processing " + testResults, e);
run.setResult(Result.FAILURE);
throw new MavenPipelinePublisherException(publisherName, "archiving JUnit results " + testResults, e);
}
}
}
Original file line number Diff line number Diff line change
@@ -220,9 +220,9 @@ public void process(@NonNull StepContext context, @NonNull Element mavenSpyLogsE
try {
jacocoPublisher.perform(run, workspace, launcher, listener);
} catch (Exception e) {
listener.error("[withMaven] jacocoPublisher - exception archiving JaCoCo results for " + jacocoReportDetails + ": " + e + ". Failing the build.");
listener.error("[withMaven] jacocoPublisher - exception archiving JaCoCo results for " + jacocoReportDetails + ": " + e);
LOGGER.log(Level.WARNING, "Exception processing JaCoCo results", e);
run.setResult(Result.FAILURE);
throw new MavenPipelinePublisherException("jacocoPublisher", "archiving JaCoCo results for " + jacocoReportDetails, e);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.jenkinsci.plugins.pipeline.maven.publishers;

public class MavenPipelinePublisherException extends RuntimeException {

private static final long serialVersionUID = -5374242713614539146L;

private String name;

private String step;

public MavenPipelinePublisherException(String name, String step, Throwable cause) {
super(name + " faced exception while " + step, cause);
this.name = name;
this.step = step;
}

public String getName() {
return name;
}

public String getStep() {
return step;
}
}
Original file line number Diff line number Diff line change
@@ -236,15 +236,14 @@ public void process(@NonNull StepContext context, @NonNull Element mavenSpyLogsE
findBugsPublisher.perform(run, workspace, launcher, listener);
} catch (Exception e) {
listener.error("[withMaven] SpotBugsPublisher - exception archiving FindBugs results for Maven artifact " + mavenArtifact.toString() + " generated by " +
pluginInvocation + ": " + e + ". Failing the build.");
pluginInvocation + ": " + e);
LOGGER.log(Level.WARNING, "Exception processing " + XmlUtils.toString(findBugsTestEvent), e);
run.setResult(Result.FAILURE);
throw new MavenPipelinePublisherException("SpotBugsPublisher",
"archiving FindBugs results for Maven artifact " + mavenArtifact.getId() + " generated by " + pluginInvocation.getId(), e);
}

}

}

@Symbol("spotbugsPublisher")
@Extension
public static class DescriptorImpl extends AbstractHealthAwarePublisher.DescriptorImpl {
Original file line number Diff line number Diff line change
@@ -170,9 +170,9 @@ public void process(@NonNull StepContext context, @NonNull Element mavenSpyLogsE
try {
tasksPublisher.perform(run, workspace, launcher, listener);
} catch (Exception e) {
listener.error("[withMaven] openTasksPublisher - exception scanning tasks in " + pattern + ": " + e + ". Failing the build.");
listener.error("[withMaven] openTasksPublisher - exception scanning tasks in " + pattern + ": " + e);
LOGGER.log(Level.WARNING, "Exception scanning tasks in " + pattern, e);
run.setResult(Result.FAILURE);
throw new MavenPipelinePublisherException("openTasksPublisher", "scanning tasks in " + pattern, e);
}
}

0 comments on commit 43b82f2

Please sign in to comment.