LDEV-323: Exceptions as objects or structs

G’day:
Micha suggested I transfer this point from Jira to here. I pretty much think we were discussing the resolution (or, in this case: lack of resolution) of a bug, but… well… so be it.

Anyhow, In Lucee exceptions are objects (CatchBlockImpl), but mostly behave like structs. They do not, however, pass the isObject() test. And whilst one can call structKeyExists() on them, one cannot call keyExists() (a different issue, and on that I believe is resolved at least in Lucee 4.5: LDEV-322)

Micha contends they ought to just behave like structs, whereas I think Exceptions are always objects, and that’s what they should stay. If they also want to implement whatever interface is required to make them pass as structs: yeah, cool, knock yourself out. But they’re still some manner of Exception object (ultimately extending java.lang.Exception).

I hasten to add this is a fairly inconsequential issue, but I always get a bit itchy when I see “weirdness” in a language, so it got me thinking. I’m all for necessary unexpected behaviour, but I’m less enthused about unexpected behaviour that doesn’t seem to have a good rationale beyond an implementation / design glitch.

Thoughts?


Adam

we should make here a difference between java name convention and CFML name convetion first.
On Java level all you have in Lucee are Objects then EVERYTHING is based on java.lang.Object, this includes string,boolean,struct …

But that is not the point, then we talk about the CFML view on this.
CFML split values in 2 groups, simple values (boolean,number,string,array,struct) and complex values (component, query …).

So the question is, is what you get in the catch block a simple or complex value? a struct or not?
if i dump it in ACF and Lucee is see a struct

so this:

try{
  throw "ddd";
}
catch(any e){
   writedump(e);
}

gives me this in ACF (even marked as struct):

and this in Lucee:

so it looks like a struct, but that’s not all, i can also use it as a struct
so all this is working fine

...
catch(any e){
    writedump(e.message);
   writedump(e.detail);
    e.susi="susanne";
   writedump(e.susi);
}

works fine with Lucee (ACF allows to set e.susi but ignores it?!)

So it something looks like a struct and works like a struct, it is a struct in my opinion.

Of course i can also to the following

...
catch(any e){
    throw e;
}

but i cannot do this, because it is a exception, i can do this because Lucee converts that to an exception…
like in this case as well

...
catch(any e){
    throw "Shit happens";
}

“Shit happens!” is a String not an exception

So for Lucee an “exception” is a struct, (it is also more than that but that does not matter) and because of that the function isObject returns false and is simpleValue and isStruct true.

So from my point of view the only question here is, should we be compatible with ACF or not?
in my opinion not, because this is a bug in ACF, as you can see in the dump they see it as a struct but it does not work as one…

I think you’re talking about two slightly different things here.

But let’s digress a bit. Regardless of what functions like isStruct() or isObject() etc return, wouldn’t it be useful if the thing (I don’t want to call it either struct or object at this stage) we deal with in case of an exception was an Exception object and not a plain old struct?

What I’m thinking about mainly is being able to have proper inheritance chains and being able to push exceptions around my system in a nicer way. Walter Seethaler (who at least @micstriit would have met, not sure about @adam_cameron) has done a lot of really cool work around a better exception handling for CFML that he shared privately with me. From what I understand a lot of the hoops he had to jump through are due to CFML just having a dumb struct for dealing with exceptions.

And to be fair - I had to deal with a lot of similar issues while working on my Facebook SDK — that comes from the PHP world where exceptions are typed objects. Therefore I’d love to have the Lucee dialect provide a proper, type exception object instead of a struct.

So - my suggestion would be twofold:

  1. Let’s try to get Walter on here - he’d be a great addition on a lot of the language discussions anyway and let him introduce and talk about the issues he was facing re exceptions
  2. Until then - let’s postpone the discussion — I think we’re actually debating this on a too narrow scope.

I tried to be more expansive with the conversation the first time around, but that didn’t pan out, so I purposely started this one with a narrower scope. Still doesn’t seem to have worked.

Your comment about inheritance chains and the like is exactly where I am trying to come from. This comment (from me) on my blog might frame things better: http://blog.adamcameron.me/2015/05/cfml-what-manner-of-object-should.html#comment-2020814379.

Cheers Kai.


Adam