|
52 | 52 | import hudson.util.Iterators; |
53 | 53 | import jenkins.model.CauseOfInterruption; |
54 | 54 | import jenkins.model.Jenkins; |
| 55 | +import org.codehaus.groovy.control.ErrorCollector; |
| 56 | +import org.codehaus.groovy.control.MultipleCompilationErrorsException; |
| 57 | +import org.codehaus.groovy.control.messages.Message; |
55 | 58 | import org.jboss.marshalling.Unmarshaller; |
56 | 59 | import org.jenkinsci.plugins.workflow.actions.ErrorAction; |
57 | 60 | import org.jenkinsci.plugins.workflow.cps.persistence.PersistIn; |
@@ -639,10 +642,60 @@ private CpsScript parseScript() throws IOException { |
639 | 642 | for (Entry<String, String> e : loadedScripts.entrySet()) { |
640 | 643 | shell.reparse(e.getKey(), e.getValue()); |
641 | 644 | } |
642 | | - } catch (MethodTooLargeException x) { |
643 | | - LOGGER.log(Level.SEVERE, "FAILED to parse WorkflowScript (the pipeline script) due to MethodTooLargeException: " + x.toString()); |
| 645 | + } catch (MethodTooLargeException | MultipleCompilationErrorsException x) { |
| 646 | + MethodTooLargeException mtlEx = null; |
| 647 | + int ecCount = 0; |
| 648 | + |
644 | 649 | closeShells(); |
645 | | - throw x; |
| 650 | + |
| 651 | + if (x instanceof MethodTooLargeException) { |
| 652 | + mtlEx = (MethodTooLargeException)x; |
| 653 | + ecCount = 1; |
| 654 | + } else if (x instanceof MultipleCompilationErrorsException) { |
| 655 | + ErrorCollector ec = ((MultipleCompilationErrorsException)x).getErrorCollector(); |
| 656 | + ecCount = ec.getErrorCount(); |
| 657 | + |
| 658 | + for (int i = 0; i < ecCount; i++) { |
| 659 | + Exception ex = ec.getException(i); |
| 660 | + if (ex == null) |
| 661 | + continue; |
| 662 | + |
| 663 | + LOGGER.log(Level.FINE, "Collected Exception #" + i + ": " + ex.toString()); |
| 664 | + if (ex instanceof MethodTooLargeException) { |
| 665 | + mtlEx = (MethodTooLargeException) ex; |
| 666 | + break; |
| 667 | + } |
| 668 | + } |
| 669 | + } |
| 670 | + |
| 671 | + if (mtlEx == null) { |
| 672 | + // Some other exception type, or collection did not include MTL, rethrow as-is |
| 673 | + throw x; |
| 674 | + } |
| 675 | + |
| 676 | + String msg = "FAILED to parse WorkflowScript (the pipeline script) due to MethodTooLargeException"; |
| 677 | + if (ecCount > 1) { |
| 678 | + msg += " (and other issues)"; |
| 679 | + } |
| 680 | + // Short message suffices, not much that a pipeline developer |
| 681 | + // can do with the stack trace into the guts of groovy |
| 682 | + msg += ": " + mtlEx.getMessage(); |
| 683 | + |
| 684 | + // Make a note in server log |
| 685 | + LOGGER.log(Level.SEVERE, msg); |
| 686 | + |
| 687 | + if (ecCount > 1) { |
| 688 | + // Not squashing with explicit MethodTooLargeException |
| 689 | + // re-thrown below, in this codepath we have other errors. |
| 690 | + throw new RuntimeException(msg, x); |
| 691 | + } else { |
| 692 | + // Do not confuse pipeline devs by a wall of text in the |
| 693 | + // build console, but let the full context be found in |
| 694 | + // server log with some dedication. |
| 695 | + LOGGER.log(Level.FINE, mtlEx.getMessage()); |
| 696 | + //throw new RuntimeException(msg, mtlEx); |
| 697 | + throw new RuntimeException(msg); |
| 698 | + } |
646 | 699 | } catch (RuntimeException | Error x) { |
647 | 700 | closeShells(); |
648 | 701 | throw x; |
|
0 commit comments