Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-35712

Failed step doesn't show as FlowNode

    XMLWordPrintable

Details

    Description

      If there is step in pipeline script with syntax error, there is error reported during the build however there is no corresponding FlowNode reported.

      Here is the sample script

      node {
        stage 'build'
        sh 'echo s1'
        stage 'test'
        echo 'Hello World 2'
      }
      parallel firstBranch: {
        echo 'Hello first'
      }, secondBranch: {
       echo 'Hello second'
       sh ssdsds
      },
      failFast: true
      

      Under the parallel 'secondBranch' the step sh ssdsds is reported as failure during pipeline execution however there is no FlowNode reported corresponding to this step. Below is the error reported in the log for this failed step:

      groovy.lang.MissingPropertyException: No such property: ssdsds for class: groovy.lang.Binding
        at groovy.lang.Binding.getVariable(Binding.java:63)
        at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:210)
        at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:241)
        at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:238)
        at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221)
        at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:23)
        at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:17)
        at WorkflowScript.run(WorkflowScript:16)
        at ___cps.transform___(Native Method)
        at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:62)
        at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
        at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.fixName(PropertyishBlock.java:54)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
        at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
        at com.cloudbees.groovy.cps.Next.step(Next.java:58)
        at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:154)
        at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:19)
        at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:33)
        at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:30)
        at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:106)
        at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:30)
        at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:164)
        at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:276)
        at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$000(CpsThreadGroup.java:78)
        at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:185)
        at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:183)
        at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:47)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:112)
        at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
      

      Attachments

        Issue Links

          Activity

            kohsuke Kohsuke Kawaguchi added a comment - - edited

            Perhaps naively, I initially thought it makes sense to create a FlowNode when an exception is thrown then I realized that this is more complicated, as there isn't an easy way to recognize the origin of the exception.

            This example could have been sh ssdsds() and when ssdsds() invocation throws an exception, we can't tell if that's because there's no such function, or whether this function actually exists and its execution has thrown an exception. If the point in which an exception is thrown is responsible for creating a record, then in the former case the point that invokes ssdsds() would add the record, but in the latter case the code inside ssdsds() should have done that.

            Maybe it's possible to have the code that catches the exception (usually CpsBodyExecution) to create a record?

            kohsuke Kohsuke Kawaguchi added a comment - - edited Perhaps naively, I initially thought it makes sense to create a FlowNode when an exception is thrown then I realized that this is more complicated, as there isn't an easy way to recognize the origin of the exception. This example could have been sh ssdsds() and when ssdsds() invocation throws an exception, we can't tell if that's because there's no such function, or whether this function actually exists and its execution has thrown an exception. If the point in which an exception is thrown is responsible for creating a record, then in the former case the point that invokes ssdsds() would add the record, but in the latter case the code inside ssdsds() should have done that. Maybe it's possible to have the code that catches the exception (usually CpsBodyExecution ) to create a record?

            Blue Ocean team seems to have some other workarounds in mind that I'm not very familiar with.

            kohsuke Kohsuke Kawaguchi added a comment - Blue Ocean team seems to have some other workarounds in mind that I'm not very familiar with.
            michaelneale Michael Neale added a comment -

            One option would be to "fail safe" and show a log if there is a failed state on job (or anything) but no corresponding step flownode. This would at least tell the user what was wrong, which is often enough.

            Not ideal though...

            michaelneale Michael Neale added a comment - One option would be to "fail safe" and show a log if there is a failed state on job (or anything) but no corresponding step flownode. This would at least tell the user what was wrong, which is often enough. Not ideal though...
            jamesdumay James Dumay added a comment -

            hrmpw / jglick any progress on this one?

            jamesdumay James Dumay added a comment - hrmpw / jglick any progress on this one?
            michaelneale Michael Neale added a comment -

            (BTW the only blue ocean workaround for this is to fall back to showing full log, none others are planned or known about).

            michaelneale Michael Neale added a comment - (BTW the only blue ocean workaround for this is to fall back to showing full log, none others are planned or known about).
            jglick Jesse Glick added a comment -

            A FlowNode is only created when there is a successful attempt to at least start a Step.

            In this case you should just see a failure attached to the end block of the parallel branch.

            jglick Jesse Glick added a comment - A FlowNode is only created when there is a successful attempt to at least start a Step . In this case you should just see a failure attached to the end block of the parallel branch.
            vivek Vivek Pandey added a comment -

            jglick I see. Referring to kohsuke's comment, something that can be implemented? Not sure what kind of changes its going to result in to though.

            michaelneale Since we show logs only for steps, we can use full log to show such errors as workaround. We flag failing node (branch or stage) status in the json DAG using parallel's endNode. If there is UI to show node level log, such error can be returned as log?

            vivek Vivek Pandey added a comment - jglick I see. Referring to kohsuke 's comment, something that can be implemented? Not sure what kind of changes its going to result in to though. michaelneale Since we show logs only for steps, we can use full log to show such errors as workaround. We flag failing node (branch or stage) status in the json DAG using parallel's endNode. If there is UI to show node level log, such error can be returned as log?
            michaelneale Michael Neale added a comment - - edited

            vivek for this to work, however, the whole job would need to return no steps, and then it will default to showing just the full log... right jamesdumay ? Or do we rely on the user to pop open the log when they see that things failed but not where? what should this look like?

            To be clear, this is a sytactic error - will show that bit error message I think right now if you try it (which is ok). With pipeline-config the error message will be clearer, but there will be no flow nodes in either case. This is ok IF this defaults to showing just the log (ie error message).

            Where this is bad is if the build starts, but then fails on that parallel branch ... then it isn't clear what to show. What is expected behavior, if we can't get a flownode?

            michaelneale Michael Neale added a comment - - edited vivek for this to work, however, the whole job would need to return no steps, and then it will default to showing just the full log... right jamesdumay ? Or do we rely on the user to pop open the log when they see that things failed but not where? what should this look like? To be clear, this is a sytactic error - will show that bit error message I think right now if you try it (which is ok). With pipeline-config the error message will be clearer, but there will be no flow nodes in either case. This is ok IF this defaults to showing just the log (ie error message). Where this is bad is if the build starts, but then fails on that parallel branch ... then it isn't clear what to show. What is expected behavior, if we can't get a flownode?

            People

              jglick Jesse Glick
              vivek Vivek Pandey
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: