Add option to callStackGet() to return omitted java traces

Currently, callStackGet() only returns CFML-related traces. (.cfc and .cfm sources.) This makes callStackGet() a bit crippled for debugging anything that touches Java or especially Lucee.

I tend to think CallStackGet() would be most useful for debugging if it included all items from the stack trace. Can we have an option to disable Lucee’s automatic filtering of the stack traces?

Syntax proposals:

  1. callStackGet( filter = "NONE" )
  2. callStackGet( showJava = true )
  3. callStackGet( filter = ( trace ) => { return listLast( trace.getFileName(), '/' ) == 'HibernateCaster.java'; } )

I really like option #3, as it allows for generic filtering on the traces without Lucee’s .java source removals. I’m unsure right now whether filtering on the original trace or Lucee’s trace result item would be better. (i.e. checking trace.getFileName() vs trace.template.)

I like the idea of getting a stack trace, but I would be included to have a separate function for it. You can also get it like so:

createObject('java','java.lang.Thread').currentThread().getStackTrace()

IMO this filtering shouldn’t be part of the BIF, but just an arrayFilter you could tack on like so

callStackGet()
  .filter( ()=>{} )

As the function returns an array and arrays are already natively filterable.

5 Likes

If the best approach is to use a .filter() after the fact, then I think it would at least be pretty nice if the stacktrace included a flag for something like “layer”? Where it could be layer: cfml, or layer: java (I’m just shooting from the hip here. Then at least the filtering could be very easy:

callstackGet().filter( ( entry ) => ( entry.layer == "cfml" ) )

I’m with @bdw429s on this.

I’d go as far as to say there’s no point adding anything to Lucee here, as it’s dead easy to get the results one wants with existing functionality. EG:

var trace = createObject('java','java.lang.Thread').currentThread().getStackTrace()
filenames = arrayMap(trace, (element) => element.getFileName()) // need to use the function rather than method here as getStackTrace returns a Java array, not a CFML one
cfcsOnly = filenames.filter((fileName) => reFind("\.cfc$", fileName))
writeDump([filenames, cfcsOnly])

Although one consideration is that the server could be locked down so that Java stuff can’t be run from CFML?

There’s be little harm in having a function getStackTrace I guess. It would be minimal work and require minimal testing. All it would need to do is call the underlying java method, and then remap each entry to be a struct, I guess. It perhaps is not ideal for a CFML function to return non-CFML data structures? Not sure.

TBH as this is not a common requirement (most ppl would never use it), and it’s already achievable now, I’d put this as really low priority, and perhaps look for someone in the community to implement it?

Hey it could be the first method in a MVP of a DebugTools module on ForgeBox! Probably no need for it to pollute CFML?

1 Like

I like the idea of getting a stack trace, but I would be included to have a separate function for it.

Fair enough, but the nomenclature would be weird. callStackGetWithJava() or callStackGetFull()? getStackTrace() is too dissimilar from callStackGet() and implies a different data type than the former.

IMO this filtering shouldn’t be part of the BIF, but just an arrayFilter you could tack on like so

Brad, I would love this syntax, but it would require changing the current behavior of callStackGet().

If “existing functionality” means “dive into Java”, then sure… there’s lots of CFML things that it’s easy to do with “existing functionality”. Doesn’t mean it’s not useful to have.

I’m also a bit lost in your example, since the whole point of this functionality is to help with java debugging… not cfc debugging. :person_shrugging:

… (most ppl would never use it),

Your overall point is fair, I can’t really argue that. If you don’t need to debug the underlying Lucee source then this method probably won’t be useful to you. And that’s a good enough reason to leave it out of the Lucee source.

Come on.

It was just a random, quick, and understandable example of how to filter the returned array to return a more focused subset of stack trace items. The predicate could have been anything. And this is the point of a generalised solution: it leaves it to the dev to achieve whatever ends they need.


Adam

1 Like