Flex/ColdFusion Mystery with a very simple answer

Yesterday I was working on a Flex project when I hit a brick wall. I had a very simple form. Flex was using remoting to send the form information to ColdFusion. ColdFusion was doing nothing with the data. It was just an empty method. However, every time I'd try to send the data I'd get an error.

Here is where things got weird. The first thing I tried was launching ServiceCapture so I could see the response from ColdFusion. However - when I would send the form data, ServiceCapture would actually hang. I had to force it down.

So then I went to my ColdFusion logs. Nothing was reported in the error log but an empty string. At this point I'm really confused. I go into my Application.cfc file's onError and added this:

<cfsavecontent variable="temp">
<cfdump var="#arguments#">
</cfsavecontent>
<cffile action="write" file="c:\foo.html" output="#temp#">

Now I get somewhere. When I look at the file, I see no message, no detail, but I do see a type for the error:

java.lang.StackOverflowError

What the heck? (Ok, I didn't say heck.) So now I start trying random crap. First I change the method names. Doesn't help. Finally I change my Flex code to send nothing to ColdFusion. And it works.

Um. Ok.

I restored my code and noticed something....

core.addAdminUser(username,password);

username and password were the form elements, not the values of the form elements. Somehow Flex thought this was ok. Can you really send a component over the wire? Flex could. And while it didn't die, it was enough to freak out ServiceCapture and ColdFusion. Changing my Flex to:

core.addAdminUser(username.text,password.text);

made everything kosher. Whew!

Coming later today - the second silly mistake I made...

Comments

I still get a few empty errors (detail and message are each "null") on my CF7 production server, and I have no idea how to identify the real nature of the problem. Does anyone know of a way to intercept the error detail before it gets passed to the error template?
# Posted By Tom Mollerus | 1/19/07 10:01 AM
Ray, Flex will do anything you ask it to. In this case AMF is being asked to serialize a component instance into AMF3 binary. The issue is that the component, has inner references to the app itself so if you pull something on the displayList or a member of the Application class, the whole thing goes with it.

It is like taking a chair out the front door and the rest of the house is dragged out the front door inside out. Careful with passing component instances through remoting. Flex will try do everything you ask.

Ted :)
# Posted By Ted Patrick | 1/19/07 10:10 AM
If you had strongly typed your core.addAdminUser to accept 2 parameters of type String, the compiler would've smacked you silly before you had a chance to get into trouble. :-)
# Posted By darron | 1/19/07 12:11 PM
Hey, I want to do the chair/house thingy. ;)
# Posted By Mike Rankin | 1/19/07 12:45 PM
Darron, good point. Would you mind posting a simple example of this? I know how to type it on the server side.
# Posted By Raymond Camden | 1/19/07 2:29 PM
Sure, but I need to see more of your code for context. What type of object is "core"? Is it just defined via the RemoteObject tag with id="core"? Assuming that's the case, the general style would be to create a wrapper class that allows you to define an interface for communicating with the server, and then invoke your RemoteObject inside of that interface:

// In a separate delegate class
public function addAdminUser( username:String, password:String )
{
core.addAdminUser( username, passwrod );
// possibly add responder here depending on what the
// rest of your code looks like
}

Then, all server communication goes through the delegate ensuring that the interface for client/server communication is the same on both ends.
# Posted By darron | 1/19/07 3:11 PM
Darron, yeah, core was my RemoteObject (talking to a CFC). Thanks for the example!
# Posted By Raymond Camden | 1/19/07 9:13 PM
I strongly recommend strict typing arguments, as well as function return types. I'm actually surprised that you were able to compile AS3/Flash 9 code w/o them. Strict typing is part of what makes Flash9 movies run 20x faster than Flash8.

public function addAdminUser( username:String, password:String ):Void
{ ... }

You 'should' strict type every function's return type, except the class constructors, which unlike ColdFusion, cannot have a return type.
# Posted By Rob Gonda | 1/19/07 10:37 PM