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

!script file name and path #344

Open
neopaf opened this issue Sep 27, 2024 · 9 comments
Open

!script file name and path #344

neopaf opened this issue Sep 27, 2024 · 9 comments

Comments

@neopaf
Copy link

neopaf commented Sep 27, 2024

Description

Currently scripts have no file name in debug info, so when I'm trying to debug them I get no breakpoints and no stepping around.

Priority

I have no budget and there's no rush, please add this feature for free

More information

Workaround: breakpoint in some lib method, like System.println and inspect whatever passed in there:
Снимок экрана 2024-09-27 в 13 43 57

(This is much faster than reading tons of manuals/sources sometimes, for some people)

Yet, it would be easier still if that debug info would've been provided.
I guess, it's pretty simple option of GoogleScriptEngine, which costs next to nothing runtime.
Maybe you'd turn it on by default (or provide some way to enable it)?

@simonbrowndotje
Copy link
Contributor

I guess, it's pretty simple option of GoogleScriptEngine, which costs next to nothing runtime.
Maybe you'd turn it on by default (or provide some way to enable it)?

I don't have any knowledge of GoogleScriptEngine, and it isn't obvious how it helps from a quick Google search. Please feel free to submit a PR or provide more information. Thanks!

@neopaf
Copy link
Author

neopaf commented Sep 27, 2024

Thanks for quick reaction, Simon.
I'm referring to object, obtained here

ScriptEngine engine = manager.getEngineByExtension(extension);

Alas, I forgot how I did it like 5 years ago.
But please consider changing this approach:

engine.eval(script.toString(), bindings);

Without name of file consequent stack trace (and IDE debugging) can not show file name (and open it in IDE, handle breakpoints), because runtime has no idea about original file name, and even if file was external (deployment.groovy), it shows this (Script136.groovy):

org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:277)
        at Script136$_run_closure2.doCall(Script136.groovy:15)

Let us start by passing eval not string, but Reader, along these lines:

if(input is external)
  engine.eval(new FileReader(scriptFile), bindings); // when input is external file; when 
else
  engine.eval(script.toString(), bindings); // as is

This will give proper file name to IDE and backtrace, hopefully enabling breakpoints and make life of script developers a tad bit happier?

@neopaf neopaf changed the title !script debug info !script file name and path Sep 27, 2024
simonbrowndotje added a commit that referenced this issue Sep 27, 2024
@simonbrowndotje
Copy link
Contributor

I've pushed some changes (see ff37cc2) ... but they only seem to work for Ruby unfortunately. If you have any further ideas, please let me know.

@neopaf
Copy link
Author

neopaf commented Sep 27, 2024

wow, that was fast, Simon. thanks for your effort. testing... will consider a bit deeper this weekend

@neopaf
Copy link
Author

neopaf commented Sep 28, 2024

For Googlers: take structurizr java, remove signing part from build.gradle,

./gradlew publishToMavenLocal 

Check out https://github.com/structurizr/lite, change structurizrVersion to 3.1.0,

./gradlew bootWar
#use build/libs/structurizr-lite.war 

Simon, thanks a lot: I'm super happy now, breakpoints and stack filtering work now:
Снимок экрана 2024-09-28 в 09 10 24

Maybe some stack trace sanitation would help, reading....

@neopaf
Copy link
Author

neopaf commented Sep 28, 2024

While IntelliJ IDEA manages to filter stack fine. Currently message has no line number where bad things in script happened:

Error

workspace.dsl: Error running script at deployment.groovy, caused by javax.script.ScriptException: javax.script.ScriptException: java.lang.reflect.UndeclaredThrowableException at line 711 of /Users/paf/Documents/Hermes/c4/./workspace.dsl: }

Neither do log files:

Name: PROD_MSK -> PROD/msk
javax.script.ScriptException: javax.script.ScriptException: java.lang.reflect.UndeclaredThrowableException
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:158)
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:132)
        at com.structurizr.dsl.ScriptDslContext.run(ScriptDslContext.java:70)
        at com.structurizr.dsl.ExternalScriptDslContext.end(ExternalScriptDslContext.java:23)
        at com.structurizr.dsl.StructurizrDslParser.endContext(StructurizrDslParser.java:1154)
        at com.structurizr.dsl.StructurizrDslParser.parse(StructurizrDslParser.java:238)
        at com.structurizr.dsl.StructurizrDslParser.parse(StructurizrDslParser.java:136)
        at com.structurizr.lite.component.workspace.FileSystemWorkspaceComponentImpl.loadWorkspaceFromDsl(FileSystemWorkspaceComponentImpl.java:146)
        at com.structurizr.lite.component.workspace.FileSystemWorkspaceComponentImpl.loadWorkspace(FileSystemWorkspaceComponentImpl.java:113)
        at com.structurizr.lite.component.workspace.FileSystemWorkspaceComponentImpl.getWorkspace(FileSystemWorkspaceComponentImpl.java:203)
        at com.structurizr.lite.web.ApiController.getWorkspace(ApiController.java:37)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:384)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
        at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: javax.script.ScriptException: java.lang.reflect.UndeclaredThrowableException
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:320)
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:155)
        ... 62 more
Caused by: java.lang.reflect.UndeclaredThrowableException
        at jdk.proxy1/jdk.proxy1.$Proxy84.accept(Unknown Source)
        at java.base/java.lang.Iterable.forEach(Iterable.java:75)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at org.codehaus.groovy.runtime.callsite.PlainObjectMetaMethodSite.doInvoke(PlainObjectMetaMethodSite.java:48)
        at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSiteNoUnwrap.invoke(PojoMetaMethodSite.java:198)
        at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:51)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139)
        at deployment.run(deployment.groovy:8)
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:317)
        ... 63 more
Caused by: java.lang.Exception: Exception while handling {{struct}} in relation[{1812 | vrf SIG | } ---[Diameter Gy запросы]---> {1839 | mn-hmsfe | }]
        at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
        at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:72)
        at org.codehaus.groovy.reflection.CachedConstructor.doConstructorInvoke(CachedConstructor.java:59)
        at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrap.callConstructor(ConstructorSite.java:84)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:59)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:263)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:286)
        at deployment$_run_closure2.doCall(deployment.groovy:22)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:274)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1030)
        at groovy.lang.Closure.call(Closure.java:427)
        at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:50)
        at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:112)
        ... 75 more
Caused by: java.lang.Exception: For DeploymentEnvironment[PROD_MSK] did not find inventory, please check deployment.groovy parameters
        at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
        at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:72)
        at org.codehaus.groovy.reflection.CachedConstructor.doConstructorInvoke(CachedConstructor.java:59)
        at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrap.callConstructor(ConstructorSite.java:84)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:59)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:263)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:277)
        at deployment$_run_closure2.doCall(deployment.groovy:15)
        ... 84 more
2024-09-28T09:06:59.536+03:00 ERROR 

@neopaf
Copy link
Author

neopaf commented Sep 28, 2024

I guess, most interesting lines with .groovy file line on them got hidden under ".... N more" cuts.

Not sure how to handle that properly.
Googling gives this: https://stackoverflow.com/questions/6259202/how-do-i-print-a-groovy-stack-trace

Not sure how to do that in properly, since you don't really know about Groovy implementation details under the ScriptEngine's hood.

@neopaf
Copy link
Author

neopaf commented Sep 28, 2024

Maybe just simple call would work, since we know that GroovyScriptEngine is on your class path.
And it removes only groovy implementation calls, not affecting any other language.
So I assume it is save to call it. Prior to printing error messages to log/ui.

@neopaf
Copy link
Author

neopaf commented Sep 29, 2024

Just call this one methods around exception to cleanup stack trace.
https://docs.groovy-lang.org/latest/html/gapi/org/codehaus/groovy/runtime/StackTraceUtils.html#sanitize(java.lang.Throwable)

Hopefully this would reach all targets...

  • in UI
  • in stack trace
    ...we'd see the line number of script

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

No branches or pull requests

2 participants