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

Improve presentation of remote exception

    XMLWordPrintable

Details

    • Bug
    • Status: Resolved (View Workflow)
    • Minor
    • Resolution: Fixed
    • remoting
    • None

    Description

      For a long time, remoting has a way to decorate received exception will a "call side" stacktrace but that is just pain to navigate even with decent application knowledge (one tells local and remote stack frames apart based on the classes involved rather then the way exception is presented). Putting aside fiddling with stacktraces the way Channel.attachCallSiteStackTrace does is dangerous at best. In Java 9 code will need to be further complicated or module information will be thrown away. Here is how it looks like now:

      java.io.IOException: Local nested
        at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:191)
        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 junit.framework.TestCase.runTest(TestCase.java:176)
        at junit.framework.TestCase.runBare(TestCase.java:141)
        at junit.framework.TestResult$1.protect(TestResult.java:122)
        at junit.framework.TestResult.runProtected(TestResult.java:142)
        at junit.framework.TestResult.run(TestResult.java:125)
        at junit.framework.TestCase.run(TestCase.java:129)
        at junit.framework.TestSuite.runTest(TestSuite.java:252)
        at junit.framework.TestSuite.run(TestSuite.java:247)
        at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:381)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:292)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
        at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
      Caused by: java.io.IOException: Node nested
        at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:197)
        at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:195)
        at hudson.remoting.UserRequest.perform(UserRequest.java:203)
        at hudson.remoting.UserRequest.perform(UserRequest.java:52)
        at hudson.remoting.Request$2.run(Request.java:356)
        at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
        at ......remote call to north(Native Method)
        at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1647)
        at hudson.remoting.UserResponse.retrieve(UserRequest.java:303)
        at hudson.remoting.Channel.call(Channel.java:896)
        at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:189)
        ... 20 more
      Caused by: java.io.IOException: Node says hello!
        at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:197)
        at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:195)
        at hudson.remoting.UserRequest.perform(UserRequest.java:203)
        at hudson.remoting.UserRequest.perform(UserRequest.java:52)
        at hudson.remoting.Request$2.run(Request.java:356)
        at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
      

      Proposal #1: Suppressed exception.

      Well, it is not a suppressed exception but it is trivial to implement and there is so little to go wrong about it. Stacktraces are untouched and the top-level exception coming from the other side has the call-site attached. The call side stacktrace is complete and clearly separated but it still requires some training to identify what is going on.

      java.io.IOException: Local nested
      	at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:191)
      	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 junit.framework.TestCase.runTest(TestCase.java:176)
      	at junit.framework.TestCase.runBare(TestCase.java:141)
      	at junit.framework.TestResult$1.protect(TestResult.java:122)
      	at junit.framework.TestResult.runProtected(TestResult.java:142)
      	at junit.framework.TestResult.run(TestResult.java:125)
      	at junit.framework.TestCase.run(TestCase.java:129)
      	at junit.framework.TestSuite.runTest(TestSuite.java:252)
      	at junit.framework.TestSuite.run(TestSuite.java:247)
      	at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
      	at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:381)
      	at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:292)
      	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
      	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
      	at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
      	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
      	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
      Caused by: java.io.IOException: Node nested
      	at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:197)
      	at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:195)
      	at hudson.remoting.UserRequest.perform(UserRequest.java:203)
      	at hudson.remoting.UserRequest.perform(UserRequest.java:52)
      	at hudson.remoting.Request$2.run(Request.java:356)
      	at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
      	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
      	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
      	at java.lang.Thread.run(Thread.java:748)
      	Suppressed: hudson.remoting.Channel$CallSiteStackTrace: Remote call to north
      		at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1647)
      		at hudson.remoting.UserResponse.retrieve(UserRequest.java:303)
      		at hudson.remoting.Channel.call(Channel.java:896)
      		at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:189)
      		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 junit.framework.TestCase.runTest(TestCase.java:176)
      		at junit.framework.TestCase.runBare(TestCase.java:141)
      		at junit.framework.TestResult$1.protect(TestResult.java:122)
      		at junit.framework.TestResult.runProtected(TestResult.java:142)
      		at junit.framework.TestResult.run(TestResult.java:125)
      		at junit.framework.TestCase.run(TestCase.java:129)
      		at junit.framework.TestSuite.runTest(TestSuite.java:252)
      		at junit.framework.TestSuite.run(TestSuite.java:247)
      		at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
      		at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:381)
      		at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:292)
      		at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
      		at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
      		at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
      		at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
      		at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
      Caused by: java.io.IOException: Node says hello!
      	... 10 more
      

      Proposal #2: Prefix stackframes with channel destination name if remote.

      This can be combined with existing approach and #1 to signify which exception (trace element) is coming from each side but it does require tempering with {{StackTraceElement}}s.

      Proposal #3: Update remote exception message with text indicating those are remote.

       

      Can be combined approach and #1. Requires reflection to work correctly. Might not have effect for certain exception types.

       

      Note sure what other ways there are but my preferred approach is #1.

      jglick,stephenconnolly,oleg_nenashev, thoughts?

      Attachments

        Activity

          olivergondza Oliver Gondža created issue -
          olivergondza Oliver Gondža made changes -
          Field Original Value New Value
          Summary Improve presentation of remot exception Improve presentation of remote exception
          olivergondza Oliver Gondža made changes -
          Description For a long time, remoting has a way to decorate received exception will a "call side" stacktrace but that is just pain to navigate even with decent application knowledge (one tells local and remote stack frames apart based on the classes involved rather then the way exception is presented). Putting aside fiddling with stacktraces the way [{{Channel.attachCallSiteStackTrace}}|https://github.com/jenkinsci/remoting/blob/967bd9448cc4b6753f0dc055d745adb89b8d8dd3/src/main/java/hudson/remoting/Channel.java#L1646] does is dangerous at best. In Java 9 code will need to be further complicated or module information will be thrown away. Here is how it looks like now:
          {noformat}
          java.io.IOException: Local nested
            at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:191)
            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 junit.framework.TestCase.runTest(TestCase.java:176)
            at junit.framework.TestCase.runBare(TestCase.java:141)
            at junit.framework.TestResult$1.protect(TestResult.java:122)
            at junit.framework.TestResult.runProtected(TestResult.java:142)
            at junit.framework.TestResult.run(TestResult.java:125)
            at junit.framework.TestCase.run(TestCase.java:129)
            at junit.framework.TestSuite.runTest(TestSuite.java:252)
            at junit.framework.TestSuite.run(TestSuite.java:247)
            at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
            at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:381)
            at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:292)
            at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
            at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
            at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
            at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
            at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
          Caused by: java.io.IOException: Node nested
            at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:197)
            at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:195)
            at hudson.remoting.UserRequest.perform(UserRequest.java:203)
            at hudson.remoting.UserRequest.perform(UserRequest.java:52)
            at hudson.remoting.Request$2.run(Request.java:356)
            at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
            at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
            at java.lang.Thread.run(Thread.java:748)
            at ......remote call to north(Native Method)
            at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1647)
            at hudson.remoting.UserResponse.retrieve(UserRequest.java:303)
            at hudson.remoting.Channel.call(Channel.java:896)
            at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:189)
            ... 20 more
          Caused by: java.io.IOException: Node says hello!
            at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:197)
            at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:195)
            at hudson.remoting.UserRequest.perform(UserRequest.java:203)
            at hudson.remoting.UserRequest.perform(UserRequest.java:52)
            at hudson.remoting.Request$2.run(Request.java:356)
            at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
            at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
            at java.lang.Thread.run(Thread.java:748)
          {noformat}
          h3. Proposal #1: Suppressed exception.

          Will, it is not a suppressed exception _but_ it is trivial to implement and there is so little to go wrong about it. Stacktraces are untouched and the top-level exception coming from the other side has the call-site attached. The call side stacktrace is complete and clearly separated but it still requires some training to identify what is going on.
          {noformat}
          java.io.IOException: Local nested
          at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:191)
          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 junit.framework.TestCase.runTest(TestCase.java:176)
          at junit.framework.TestCase.runBare(TestCase.java:141)
          at junit.framework.TestResult$1.protect(TestResult.java:122)
          at junit.framework.TestResult.runProtected(TestResult.java:142)
          at junit.framework.TestResult.run(TestResult.java:125)
          at junit.framework.TestCase.run(TestCase.java:129)
          at junit.framework.TestSuite.runTest(TestSuite.java:252)
          at junit.framework.TestSuite.run(TestSuite.java:247)
          at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:381)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:292)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
          at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
          at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
          at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
          at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
          Caused by: java.io.IOException: Node nested
          at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:197)
          at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:195)
          at hudson.remoting.UserRequest.perform(UserRequest.java:203)
          at hudson.remoting.UserRequest.perform(UserRequest.java:52)
          at hudson.remoting.Request$2.run(Request.java:356)
          at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
          at java.util.concurrent.FutureTask.run(FutureTask.java:266)
          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
          at java.lang.Thread.run(Thread.java:748)
          Suppressed: hudson.remoting.Channel$CallSiteStackTrace: Remote call to north
          at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1647)
          at hudson.remoting.UserResponse.retrieve(UserRequest.java:303)
          at hudson.remoting.Channel.call(Channel.java:896)
          at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:189)
          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 junit.framework.TestCase.runTest(TestCase.java:176)
          at junit.framework.TestCase.runBare(TestCase.java:141)
          at junit.framework.TestResult$1.protect(TestResult.java:122)
          at junit.framework.TestResult.runProtected(TestResult.java:142)
          at junit.framework.TestResult.run(TestResult.java:125)
          at junit.framework.TestCase.run(TestCase.java:129)
          at junit.framework.TestSuite.runTest(TestSuite.java:252)
          at junit.framework.TestSuite.run(TestSuite.java:247)
          at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:381)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:292)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
          at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
          at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
          at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
          at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
          Caused by: java.io.IOException: Node says hello!
          ... 10 more
          {noformat}
          h3. Proposal #2: Prefix stackframes with channel destination name if remote.

          This can be combined with existing approach and #1 to signify which exception (trace element) if coming from each side but it does require tempering with \{\{StackTraceElement}}s.
          h3. Proposal #3: Update remote exception message with text indicating those are remote.

           

          Again, can be combined with current approach and #1. Requires reflection to work correctly. Might not have effect for certain exception types.

           

          Note sure what other ways there are but my preferred approach is #1.

          [~jglick],[~stephenconnolly],[~oleg_nenashev], thoughts?
          For a long time, remoting has a way to decorate received exception will a "call side" stacktrace but that is just pain to navigate even with decent application knowledge (one tells local and remote stack frames apart based on the classes involved rather then the way exception is presented). Putting aside fiddling with stacktraces the way [{{Channel.attachCallSiteStackTrace}}|https://github.com/jenkinsci/remoting/blob/967bd9448cc4b6753f0dc055d745adb89b8d8dd3/src/main/java/hudson/remoting/Channel.java#L1646] does is dangerous at best. In Java 9 code will need to be further complicated or module information will be thrown away. Here is how it looks like now:
          {noformat}
          java.io.IOException: Local nested
            at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:191)
            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 junit.framework.TestCase.runTest(TestCase.java:176)
            at junit.framework.TestCase.runBare(TestCase.java:141)
            at junit.framework.TestResult$1.protect(TestResult.java:122)
            at junit.framework.TestResult.runProtected(TestResult.java:142)
            at junit.framework.TestResult.run(TestResult.java:125)
            at junit.framework.TestCase.run(TestCase.java:129)
            at junit.framework.TestSuite.runTest(TestSuite.java:252)
            at junit.framework.TestSuite.run(TestSuite.java:247)
            at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
            at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:381)
            at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:292)
            at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
            at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
            at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
            at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
            at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
          Caused by: java.io.IOException: Node nested
            at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:197)
            at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:195)
            at hudson.remoting.UserRequest.perform(UserRequest.java:203)
            at hudson.remoting.UserRequest.perform(UserRequest.java:52)
            at hudson.remoting.Request$2.run(Request.java:356)
            at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
            at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
            at java.lang.Thread.run(Thread.java:748)
            at ......remote call to north(Native Method)
            at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1647)
            at hudson.remoting.UserResponse.retrieve(UserRequest.java:303)
            at hudson.remoting.Channel.call(Channel.java:896)
            at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:189)
            ... 20 more
          Caused by: java.io.IOException: Node says hello!
            at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:197)
            at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:195)
            at hudson.remoting.UserRequest.perform(UserRequest.java:203)
            at hudson.remoting.UserRequest.perform(UserRequest.java:52)
            at hudson.remoting.Request$2.run(Request.java:356)
            at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
            at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
            at java.lang.Thread.run(Thread.java:748)
          {noformat}
          h3. Proposal #1: Suppressed exception.

          Will, it is not a suppressed exception _but_ it is trivial to implement and there is so little to go wrong about it. Stacktraces are untouched and the top-level exception coming from the other side has the call-site attached. The call side stacktrace is complete and clearly separated but it still requires some training to identify what is going on.
          {noformat}
          java.io.IOException: Local nested
          at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:191)
          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 junit.framework.TestCase.runTest(TestCase.java:176)
          at junit.framework.TestCase.runBare(TestCase.java:141)
          at junit.framework.TestResult$1.protect(TestResult.java:122)
          at junit.framework.TestResult.runProtected(TestResult.java:142)
          at junit.framework.TestResult.run(TestResult.java:125)
          at junit.framework.TestCase.run(TestCase.java:129)
          at junit.framework.TestSuite.runTest(TestSuite.java:252)
          at junit.framework.TestSuite.run(TestSuite.java:247)
          at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:381)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:292)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
          at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
          at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
          at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
          at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
          Caused by: java.io.IOException: Node nested
          at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:197)
          at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:195)
          at hudson.remoting.UserRequest.perform(UserRequest.java:203)
          at hudson.remoting.UserRequest.perform(UserRequest.java:52)
          at hudson.remoting.Request$2.run(Request.java:356)
          at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
          at java.util.concurrent.FutureTask.run(FutureTask.java:266)
          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
          at java.lang.Thread.run(Thread.java:748)
          Suppressed: hudson.remoting.Channel$CallSiteStackTrace: Remote call to north
          at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1647)
          at hudson.remoting.UserResponse.retrieve(UserRequest.java:303)
          at hudson.remoting.Channel.call(Channel.java:896)
          at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:189)
          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 junit.framework.TestCase.runTest(TestCase.java:176)
          at junit.framework.TestCase.runBare(TestCase.java:141)
          at junit.framework.TestResult$1.protect(TestResult.java:122)
          at junit.framework.TestResult.runProtected(TestResult.java:142)
          at junit.framework.TestResult.run(TestResult.java:125)
          at junit.framework.TestCase.run(TestCase.java:129)
          at junit.framework.TestSuite.runTest(TestSuite.java:252)
          at junit.framework.TestSuite.run(TestSuite.java:247)
          at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:381)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:292)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
          at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
          at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
          at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
          at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
          Caused by: java.io.IOException: Node says hello!
          ... 10 more
          {noformat}
          h3. Proposal #2: Prefix stackframes with channel destination name if remote.

          This can be combined with existing approach and #1 to signify which exception (trace element) is coming from each side but it does require tempering with \{\{StackTraceElement}}s.
          h3. Proposal #3: Update remote exception message with text indicating those are remote.

           

          Can be combined approach and #1. Requires reflection to work correctly. Might not have effect for certain exception types.

           

          Note sure what other ways there are but my preferred approach is #1.

          [~jglick],[~stephenconnolly],[~oleg_nenashev], thoughts?
          olivergondza Oliver Gondža made changes -
          Description For a long time, remoting has a way to decorate received exception will a "call side" stacktrace but that is just pain to navigate even with decent application knowledge (one tells local and remote stack frames apart based on the classes involved rather then the way exception is presented). Putting aside fiddling with stacktraces the way [{{Channel.attachCallSiteStackTrace}}|https://github.com/jenkinsci/remoting/blob/967bd9448cc4b6753f0dc055d745adb89b8d8dd3/src/main/java/hudson/remoting/Channel.java#L1646] does is dangerous at best. In Java 9 code will need to be further complicated or module information will be thrown away. Here is how it looks like now:
          {noformat}
          java.io.IOException: Local nested
            at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:191)
            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 junit.framework.TestCase.runTest(TestCase.java:176)
            at junit.framework.TestCase.runBare(TestCase.java:141)
            at junit.framework.TestResult$1.protect(TestResult.java:122)
            at junit.framework.TestResult.runProtected(TestResult.java:142)
            at junit.framework.TestResult.run(TestResult.java:125)
            at junit.framework.TestCase.run(TestCase.java:129)
            at junit.framework.TestSuite.runTest(TestSuite.java:252)
            at junit.framework.TestSuite.run(TestSuite.java:247)
            at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
            at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:381)
            at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:292)
            at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
            at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
            at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
            at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
            at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
          Caused by: java.io.IOException: Node nested
            at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:197)
            at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:195)
            at hudson.remoting.UserRequest.perform(UserRequest.java:203)
            at hudson.remoting.UserRequest.perform(UserRequest.java:52)
            at hudson.remoting.Request$2.run(Request.java:356)
            at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
            at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
            at java.lang.Thread.run(Thread.java:748)
            at ......remote call to north(Native Method)
            at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1647)
            at hudson.remoting.UserResponse.retrieve(UserRequest.java:303)
            at hudson.remoting.Channel.call(Channel.java:896)
            at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:189)
            ... 20 more
          Caused by: java.io.IOException: Node says hello!
            at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:197)
            at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:195)
            at hudson.remoting.UserRequest.perform(UserRequest.java:203)
            at hudson.remoting.UserRequest.perform(UserRequest.java:52)
            at hudson.remoting.Request$2.run(Request.java:356)
            at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
            at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
            at java.lang.Thread.run(Thread.java:748)
          {noformat}
          h3. Proposal #1: Suppressed exception.

          Will, it is not a suppressed exception _but_ it is trivial to implement and there is so little to go wrong about it. Stacktraces are untouched and the top-level exception coming from the other side has the call-site attached. The call side stacktrace is complete and clearly separated but it still requires some training to identify what is going on.
          {noformat}
          java.io.IOException: Local nested
          at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:191)
          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 junit.framework.TestCase.runTest(TestCase.java:176)
          at junit.framework.TestCase.runBare(TestCase.java:141)
          at junit.framework.TestResult$1.protect(TestResult.java:122)
          at junit.framework.TestResult.runProtected(TestResult.java:142)
          at junit.framework.TestResult.run(TestResult.java:125)
          at junit.framework.TestCase.run(TestCase.java:129)
          at junit.framework.TestSuite.runTest(TestSuite.java:252)
          at junit.framework.TestSuite.run(TestSuite.java:247)
          at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:381)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:292)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
          at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
          at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
          at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
          at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
          Caused by: java.io.IOException: Node nested
          at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:197)
          at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:195)
          at hudson.remoting.UserRequest.perform(UserRequest.java:203)
          at hudson.remoting.UserRequest.perform(UserRequest.java:52)
          at hudson.remoting.Request$2.run(Request.java:356)
          at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
          at java.util.concurrent.FutureTask.run(FutureTask.java:266)
          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
          at java.lang.Thread.run(Thread.java:748)
          Suppressed: hudson.remoting.Channel$CallSiteStackTrace: Remote call to north
          at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1647)
          at hudson.remoting.UserResponse.retrieve(UserRequest.java:303)
          at hudson.remoting.Channel.call(Channel.java:896)
          at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:189)
          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 junit.framework.TestCase.runTest(TestCase.java:176)
          at junit.framework.TestCase.runBare(TestCase.java:141)
          at junit.framework.TestResult$1.protect(TestResult.java:122)
          at junit.framework.TestResult.runProtected(TestResult.java:142)
          at junit.framework.TestResult.run(TestResult.java:125)
          at junit.framework.TestCase.run(TestCase.java:129)
          at junit.framework.TestSuite.runTest(TestSuite.java:252)
          at junit.framework.TestSuite.run(TestSuite.java:247)
          at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:381)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:292)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
          at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
          at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
          at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
          at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
          Caused by: java.io.IOException: Node says hello!
          ... 10 more
          {noformat}
          h3. Proposal #2: Prefix stackframes with channel destination name if remote.

          This can be combined with existing approach and #1 to signify which exception (trace element) is coming from each side but it does require tempering with \{\{StackTraceElement}}s.
          h3. Proposal #3: Update remote exception message with text indicating those are remote.

           

          Can be combined approach and #1. Requires reflection to work correctly. Might not have effect for certain exception types.

           

          Note sure what other ways there are but my preferred approach is #1.

          [~jglick],[~stephenconnolly],[~oleg_nenashev], thoughts?
          For a long time, remoting has a way to decorate received exception will a "call side" stacktrace but that is just pain to navigate even with decent application knowledge (one tells local and remote stack frames apart based on the classes involved rather then the way exception is presented). Putting aside fiddling with stacktraces the way [{{Channel.attachCallSiteStackTrace}}|https://github.com/jenkinsci/remoting/blob/967bd9448cc4b6753f0dc055d745adb89b8d8dd3/src/main/java/hudson/remoting/Channel.java#L1646] does is dangerous at best. In Java 9 code will need to be further complicated or module information will be thrown away. Here is how it looks like now:
          {noformat}
          java.io.IOException: Local nested
            at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:191)
            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 junit.framework.TestCase.runTest(TestCase.java:176)
            at junit.framework.TestCase.runBare(TestCase.java:141)
            at junit.framework.TestResult$1.protect(TestResult.java:122)
            at junit.framework.TestResult.runProtected(TestResult.java:142)
            at junit.framework.TestResult.run(TestResult.java:125)
            at junit.framework.TestCase.run(TestCase.java:129)
            at junit.framework.TestSuite.runTest(TestSuite.java:252)
            at junit.framework.TestSuite.run(TestSuite.java:247)
            at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
            at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:381)
            at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:292)
            at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
            at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
            at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
            at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
            at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
          Caused by: java.io.IOException: Node nested
            at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:197)
            at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:195)
            at hudson.remoting.UserRequest.perform(UserRequest.java:203)
            at hudson.remoting.UserRequest.perform(UserRequest.java:52)
            at hudson.remoting.Request$2.run(Request.java:356)
            at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
            at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
            at java.lang.Thread.run(Thread.java:748)
            at ......remote call to north(Native Method)
            at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1647)
            at hudson.remoting.UserResponse.retrieve(UserRequest.java:303)
            at hudson.remoting.Channel.call(Channel.java:896)
            at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:189)
            ... 20 more
          Caused by: java.io.IOException: Node says hello!
            at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:197)
            at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:195)
            at hudson.remoting.UserRequest.perform(UserRequest.java:203)
            at hudson.remoting.UserRequest.perform(UserRequest.java:52)
            at hudson.remoting.Request$2.run(Request.java:356)
            at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
            at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
            at java.lang.Thread.run(Thread.java:748)
          {noformat}
          h3. Proposal #1: Suppressed exception.

          Well, it is not a suppressed exception _but_ it is trivial to implement and there is so little to go wrong about it. Stacktraces are untouched and the top-level exception coming from the other side has the call-site attached. The call side stacktrace is complete and clearly separated but it still requires some training to identify what is going on.
          {noformat}
          java.io.IOException: Local nested
          at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:191)
          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 junit.framework.TestCase.runTest(TestCase.java:176)
          at junit.framework.TestCase.runBare(TestCase.java:141)
          at junit.framework.TestResult$1.protect(TestResult.java:122)
          at junit.framework.TestResult.runProtected(TestResult.java:142)
          at junit.framework.TestResult.run(TestResult.java:125)
          at junit.framework.TestCase.run(TestCase.java:129)
          at junit.framework.TestSuite.runTest(TestSuite.java:252)
          at junit.framework.TestSuite.run(TestSuite.java:247)
          at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:381)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:292)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
          at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
          at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
          at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
          at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
          Caused by: java.io.IOException: Node nested
          at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:197)
          at hudson.remoting.ChannelTest$ThrowingCallable.call(ChannelTest.java:195)
          at hudson.remoting.UserRequest.perform(UserRequest.java:203)
          at hudson.remoting.UserRequest.perform(UserRequest.java:52)
          at hudson.remoting.Request$2.run(Request.java:356)
          at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
          at java.util.concurrent.FutureTask.run(FutureTask.java:266)
          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
          at java.lang.Thread.run(Thread.java:748)
          Suppressed: hudson.remoting.Channel$CallSiteStackTrace: Remote call to north
          at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1647)
          at hudson.remoting.UserResponse.retrieve(UserRequest.java:303)
          at hudson.remoting.Channel.call(Channel.java:896)
          at hudson.remoting.ChannelTest.testCallSiteStacktrace(ChannelTest.java:189)
          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 junit.framework.TestCase.runTest(TestCase.java:176)
          at junit.framework.TestCase.runBare(TestCase.java:141)
          at junit.framework.TestResult$1.protect(TestResult.java:122)
          at junit.framework.TestResult.runProtected(TestResult.java:142)
          at junit.framework.TestResult.run(TestResult.java:125)
          at junit.framework.TestCase.run(TestCase.java:129)
          at junit.framework.TestSuite.runTest(TestSuite.java:252)
          at junit.framework.TestSuite.run(TestSuite.java:247)
          at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:381)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:292)
          at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
          at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
          at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
          at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
          at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
          Caused by: java.io.IOException: Node says hello!
          ... 10 more
          {noformat}
          h3. Proposal #2: Prefix stackframes with channel destination name if remote.

          This can be combined with existing approach and #1 to signify which exception (trace element) is coming from each side but it does require tempering with \{\{StackTraceElement}}s.
          h3. Proposal #3: Update remote exception message with text indicating those are remote.

           

          Can be combined approach and #1. Requires reflection to work correctly. Might not have effect for certain exception types.

           

          Note sure what other ways there are but my preferred approach is #1.

          [~jglick],[~stephenconnolly],[~oleg_nenashev], thoughts?
          oleg_nenashev Oleg Nenashev added a comment -

          I definitely vote for #1 and #2.

          #3 seems to be more complicated to me, maybe we would rather like to introduce a "RemoteException" wrapper. Actually it's already kinda exists for serializing non-serializable exceptions, but we could improve it and add our own exception rendering.

          oleg_nenashev Oleg Nenashev added a comment - I definitely vote for #1 and #2. #3 seems to be more complicated to me, maybe we would rather like to introduce a "RemoteException" wrapper. Actually it's already kinda exists for serializing non-serializable exceptions, but we could improve it and add our own exception rendering.
          oleg_nenashev Oleg Nenashev made changes -
          Epic Link JENKINS-46154 [ 184393 ]

          I do not think there is a way to implement wrapper as the call is supposed to throw exception of type parameter of Callable.

          olivergondza Oliver Gondža added a comment - I do not think there is a way to implement wrapper as the call is supposed to throw exception of type parameter of Callable .

          No further opinions so I stick with the simplest improvement.

          olivergondza Oliver Gondža added a comment - No further opinions so I stick with the simplest improvement.
          jglick Jesse Glick added a comment -

          #1 seems fine.

          Note that current versions of Jenkins core will display causes and suppressed throwables a little differently from the Java default. Best to show that. (cf. Functions.printThrowable)

          jglick Jesse Glick added a comment - #1 seems fine. Note that current versions of Jenkins core will display causes and suppressed throwables a little differently from the Java default. Best to show that. (cf. Functions.printThrowable )

          Code changed in jenkins
          User: Oliver Gondža
          Path:
          src/main/java/hudson/remoting/Channel.java
          src/test/java/hudson/remoting/ChannelTest.java
          http://jenkins-ci.org/commit/remoting/ef7e916883f1818023a11776ff4d2057eaf39fd5
          Log:
          [FIXED JENKINS-46140] Improve presentation of remote exception

          scm_issue_link SCM/JIRA link daemon added a comment - Code changed in jenkins User: Oliver Gondža Path: src/main/java/hudson/remoting/Channel.java src/test/java/hudson/remoting/ChannelTest.java http://jenkins-ci.org/commit/remoting/ef7e916883f1818023a11776ff4d2057eaf39fd5 Log: [FIXED JENKINS-46140] Improve presentation of remote exception
          scm_issue_link SCM/JIRA link daemon made changes -
          Resolution Fixed [ 1 ]
          Status Open [ 1 ] Resolved [ 5 ]

          Code changed in jenkins
          User: Oleg Nenashev
          Path:
          src/main/java/hudson/remoting/Channel.java
          src/test/java/hudson/remoting/ChannelTest.java
          http://jenkins-ci.org/commit/remoting/4f8e9da5c75b48013428df2bbbb6517d80122304
          Log:
          Merge pull request #189 from olivergondza/JENKINS-46140

          [FIXED JENKINS-46140] Improve presentation of remote exception

          Compare: https://github.com/jenkinsci/remoting/compare/c9d858a50cea...4f8e9da5c75b

          scm_issue_link SCM/JIRA link daemon added a comment - Code changed in jenkins User: Oleg Nenashev Path: src/main/java/hudson/remoting/Channel.java src/test/java/hudson/remoting/ChannelTest.java http://jenkins-ci.org/commit/remoting/4f8e9da5c75b48013428df2bbbb6517d80122304 Log: Merge pull request #189 from olivergondza/ JENKINS-46140 [FIXED JENKINS-46140] Improve presentation of remote exception Compare: https://github.com/jenkinsci/remoting/compare/c9d858a50cea...4f8e9da5c75b

          Code changed in jenkins
          User: Oleg Nenashev
          Path:
          pom.xml
          http://jenkins-ci.org/commit/jenkins/018f9875ca58230afc4eb52ac66b3195f00128ef
          Log:
          [JENKINS-45755, JENKINS-46140] - Update Remoting to 3.12

          https://github.com/jenkinsci/remoting/blob/master/CHANGELOG.md#312

          scm_issue_link SCM/JIRA link daemon added a comment - Code changed in jenkins User: Oleg Nenashev Path: pom.xml http://jenkins-ci.org/commit/jenkins/018f9875ca58230afc4eb52ac66b3195f00128ef Log: [JENKINS-45755, JENKINS-46140] - Update Remoting to 3.12 https://github.com/jenkinsci/remoting/blob/master/CHANGELOG.md#312

          Code changed in jenkins
          User: Oleg Nenashev
          Path:
          pom.xml
          http://jenkins-ci.org/commit/jenkins/e8b2f5a59c0b075f62bea9b6a45ef35a1c2ca1bb
          Log:
          Merge pull request #3025 from oleg-nenashev/remoting/3.12

          [JENKINS-45755, JENKINS-46140] - Update Remoting to 3.12

          Compare: https://github.com/jenkinsci/jenkins/compare/2343909f0240...e8b2f5a59c0b

          scm_issue_link SCM/JIRA link daemon added a comment - Code changed in jenkins User: Oleg Nenashev Path: pom.xml http://jenkins-ci.org/commit/jenkins/e8b2f5a59c0b075f62bea9b6a45ef35a1c2ca1bb Log: Merge pull request #3025 from oleg-nenashev/remoting/3.12 [JENKINS-45755, JENKINS-46140] - Update Remoting to 3.12 Compare: https://github.com/jenkinsci/jenkins/compare/2343909f0240...e8b2f5a59c0b

          People

            olivergondza Oliver Gondža
            olivergondza Oliver Gondža
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: