0

So I have a remote ColdFusion Function like:

remote string function name (required numeric varname){

This is accessed via AJAX call. Google has taken it upon itself to pass in junk/blank values to the URL to this remote function. How can I gracefully handle those for Bots/Users to manage to get in a junk value. I've tried putting try/catch around/inside the function and doesn't work. I've also tried setting a default value but I still get an error. I'd like to be able to return an error message.

Thoughts?

Right now:

domain.com/path/to/page.cfc?method=function&varname=

Is throwing an error

domain.com/path/to/page.cfc?method=function&varname=5

Is working as expected.

Leigh
  • 28,765
  • 10
  • 55
  • 103
Leeish
  • 5,203
  • 2
  • 17
  • 45

2 Answers2

4

Update:

I am leaving this here for posterity, as it explains the cause of the error and chain of events with validation. However, Adam's response is the correct solution IMO.


remote string function name (required numeric varname){

I've tried putting try/catch around/inside the function and doesn't work.

Because the argument value is validated before CF executes anything inside the function. So it never even gets to the try/catch.

If you want to allow non-numeric values, you must set the argument type to string and perform validation inside the function. ie

      // use whatever check is appropriate here
      if ( IsNumeric(arguments.varname) ) { 
          // good value. do something
      }
      else {
          // bad value. do something else
      }

I've also tried setting a default value but I still get an error

domain.com/path/to/page.cfc?method=function&varname=

Update The reason it does not work is because the varname parameter does exists. Its value is an empty string. As long as some value is passed (even an empty string) the default is ignored.

Community
  • 1
  • 1
Leigh
  • 28,765
  • 10
  • 55
  • 103
  • Well I don't WANT to allow non-numeric values. Thus the `numeric` in the argument declaration. But if that is the only way to do it I can do a `isNumeric` check. That seems sub-optimal. No other ways? – Leeish Mar 28 '13 at 17:45
  • 2
    *No other ways* Not really. You cannot have it both ways. Using `numeric` says you want to reject non-numeric values, which is exactly what is happening. You just do not have control over the error returned. In other languages you could probably use overloading to create a version that accepts `string`, and returns a custom error message. AFAIK there is no way to do that in CF. (Edit: I am not 100% positive about CF10 though). – Leigh Mar 28 '13 at 17:49
  • While not as granular, what about implementing a general try/catch inside [onCFCRequest](http://help.adobe.com/en_US/ColdFusion/10.0/CFMLRef/WSe821657cd7d6f83f6daaa733122cf6931bb-8000.html)? "Catch" that specific validation error and output a custom error message instead. – Leigh Mar 28 '13 at 19:16
  • I have a common error handler that handles all errors effectively, and is handling this one. While a general onCFCRequest (Which I didn't know existed) would work too, I want to return a specific error message in regards to this function. So I think your first answer is the one I want. If I had been the one designing all of these applications from the get go, I would use that onCFCRequest and push a common `object.error` value and all my requests would look for that. It's not currently the case. – Leeish Mar 28 '13 at 19:32
  • I agree that it may seem sub-optimal, but I just ran a test case looping through using `isNumeric()` 50,000 times and the total processing time (for 50,000 runs) was between 0 and 31ms every time. – Matt Busche Mar 28 '13 at 19:37
3

I disagree that the accepted solution is the best approach here.

Firstly, if your method is expecting a numeric and it's being passed a string, then an error is precisely the correct reaction here. You shouldn't feel the need to mitigate for requests that pass invalid values. Consider it like someone making a request to http://some.domain/path/to/file/wrongOne.html (they should have requested http://some.domain/path/to/file/rightOne.html)... it's completely OK for things to return a 404 "error" there, isn't it? An error response is exactly right in that situation.

Similarly, you have dictated that for your remote call URL, that argument is supposed to be numeric. So if it's not numeric... that is an error condition. So your server returning a 500-type error is actually the correct thing to do.

This is an example of the "garbage in, garbage out" rule.

If you are looking for an elegant solution, I'd say you already have the most elegant solution. Don't mess around writing special code to deal with incorrectly made requests. That is not an elegant approach.

You are better off letting the thing error, because then the mechanism requesting the URL will stop doing it. Messing around so that you are returning a 200 OK for a request that wasn't "OK" is the wrong thing to do.

Errors - when they are the correct result - are fine. There's nothing wrong with them.

Adam Cameron
  • 29,677
  • 4
  • 37
  • 78
  • (Edit - Darn this 5 minute time limit!) I would agree with that. Like I mentioned in the comments, the validation is doing what it should do. But my response was more focused on explaining the chain of events and the available options. I left out the most important one: if it should fail, let it. – Leigh Mar 28 '13 at 21:01
  • That's OK. It's given my a topic for my blog today, anyhow ;-) – Adam Cameron Mar 28 '13 at 21:01
  • Haha, glad to be of service ;-) I look forward to seeing what you come up with, so do post a link when it is done. – Leigh Mar 28 '13 at 21:06
  • Then riddle me this. My server emails me in the onError function. That way I can see if there is a bug in the code and fix it. I often use this chance to put in try/catch statements to provide feedback in case something goes wrong. I HATE getting error emails when Bots put in junk. What's the best course of action. Delete the email and look at it as a part of the job, or design my code so ALL errors are given feedback. Almost all of our errors are caught in the onError function, but I often like to finish a page load/request and tell them something went wrong. – Leeish Mar 29 '13 at 02:54
  • My thought is I'd rather catch the errors where they happen and tell the user there was malformed data etc, rather than let the onError function catch it and display half a page with a generic something went wrong error. With REMOTE functions it appears I cannot truly have it both ways and have simplified code. – Leeish Mar 29 '13 at 02:57
  • But like you said... these errors come from misuse of the function anyhow (probably by a bot), so you're either giving a nice message to a bot (who won't care), or a hacker (who you should not be helping). When used correctly, this is being called via AJAX, yes? In which case what you should be dealing with the 500 error on the client side and saying "something went wrong", it still should not be handled by your method code. – Adam Cameron Mar 29 '13 at 03:18