Copy link to clipboard
Copied
I have a CFC method that uses a cfscript to define a structure that is initialized with details from a query and used to create an HTML output which is saved using <cfsavecontent>. The compressed html struct is then returned to the calling AJAX to render the output on the screen. I cannot post the code because of company policies but the url looks something like this : http://appurl/componenetName.cfc?method=methodname&returnFormat=json. Now during a security testing, the person replaced the json with 'abc' and it throws an invalid Return Format - which is totally acceptable, but - I want to show a general application Application error instead of the CF error. How and where do I catch this error? Will a cftry and cfcatch work? I tried defining error in the ajax call but I still get the error. I tried to use if,else to see if no input is passed to throw the error, but that still doesnt change the invalid returnType. Any help on this will highly appreciated.
PS: I am new to CF, been only 6 months so please respond with a simple expalnantion. Thanks in advance.
The problem is the error is not being thrown insode the CFC function it is thrown when the function is called so you cannot trap it insode the function. Per documentation the only valid values for ReturnFormat are JSON, PLAIN or WDDX, anthing else will result in an error on the call. The only way to trap this is to use the OnError in the Application CFC.
See article by Ben Nadel https://www.bennadel.com/blog/1567-handling-remote-api-errors-with-application-cfcs-onerror-event-method.htm
Copy link to clipboard
Copied
Hello, and welcome to ColdFusion. I hope you enjoy working CF as much as I do.
A CFTRY/CFCATCH could work well, and you can use the catch to return a simple error message to the user for display, and also use that to CFMAIL a CFDUMP of the error message (#cfcatch#) to yourself. At least that is how I would handle it. I'm sure there are others who can also provide some really good ideas.
HTH,
^ _ ^
Copy link to clipboard
Copied
The problem is the error is not being thrown insode the CFC function it is thrown when the function is called so you cannot trap it insode the function. Per documentation the only valid values for ReturnFormat are JSON, PLAIN or WDDX, anthing else will result in an error on the call. The only way to trap this is to use the OnError in the Application CFC.
See article by Ben Nadel https://www.bennadel.com/blog/1567-handling-remote-api-errors-with-application-cfcs-onerror-event-me...
Copy link to clipboard
Copied
I like the method suggested by John1231 . But I disagree that it is the only way.
You could also use the tag <cferror>.
For example, proceed as follows:
1) In the same directory as Application.cfc, create a new page, errorHandler.cfm, to handle errors.
2) Add a cferror tag to Application.cfc, immediately following the "this" settings. Set the tag's template attribute to "errorhandler.cfm".
That's it.
Application.cfc
<cfcomponent displayname="Application" output="true" hint="Handle the application.">
<!--- Set up the application. --->
<cfset this.Name = "myApp">
<cfset this.ApplicationTimeout = createTimeSpan( 1, 0, 0, 0 )>
<cfset this.sessionTimeout = createTimeSpan( 0, 0, 30, 0 )>
<cfset this.sessionManagement = true />
<cferror template="errorHandler.cfm" type="exception" exception="any">
<cffunction
name="OnApplicationStart"
access="public"
returntype="boolean"
output="false"
hint="Fires when the application is first created.">
<cfreturn true>
</cffunction>
</cfcomponent>
errorHandler.cfm
<!---
Dump the details of the error. Select the information you will need to show.
Then comment out this dump code and proceed such as in the example below.
--->
<!---<cfdump var="#error#" label="Error struct in errorHandler">--->
<cfif findNoCase("invalid returnFormat", error.message) gt 0>
You specified the wrong value for <b>returnFormat</b>. The value you specify must be <b>wddx</b>, <b>plain</b> or <b>json</b>.
</cfif>
Copy link to clipboard
Copied
Thanks for this BKBK, I don't remember ever using CFERROR before. I always use the onError for global error traps.
Copy link to clipboard
Copied
Your answer was super helpful too. Thanks for making it so clear and giving me the examples. It helped me a lot.
Copy link to clipboard
Copied
Yes, I understood that the error was being thrown outside the function when the try and catch werent working. I tried the <cferror> tag also suggested by @BKBK, however, it kept throwing me a could not resolve cfm file error even thought it was in the same folder. I might required to add a mapping to fix the error, so instead I used the onError method and it worked like a charm. Thank you so much for your help 🙂
Copy link to clipboard
Copied
I'm curious, though. If the CFFUNCTION were placed within a CFTRY/CFCATCH, would that work? Or is that not canon?
V/r,
^ _ ^
Copy link to clipboard
Copied
I'm suddenly unable to edit my messages. In FF and Chrome.
Anyhoo, I can answer my question. If the application.cfc has an onError function, that will trigger before the CATCH. Can't try it without the onError.
V/r,
^ _ ^
Copy link to clipboard
Copied
Actually, I just thought of something else. Whitelisting. In the CFC, near the top, use a switch/case that uses the valid formats, and set a default to JSON if nothing matches. Voila. Problem solved.
<cfswitch expression="#arguments.returnFormat#">
<cfcase value="JSON,WDDX,XML,PLAIN" delimiters=",">
<!--- Do nothing; it's valid! --->
</cfcase>
<cfdefaultcase>
<!--- Someone is trying something they shouldn't be trying --->
<cfset arguments.returnFormat = "JSON" />
</cfdefaultcase>
</cfswitch>
HTH,
^ _ ^
Copy link to clipboard
Copied
So, I've been playing around. I created a CFC that will return a CFDUMP of the function called.
test.cfc:
<cffunction name="myTest1" access="remote" description="This is only a test to see what is returned." output="no" returnformat="plain" secureJSON="no">
<cfsavecontent variable="variables.thisStuff">
<cfdump var="#this.myTest1#" />
</cfsavecontent>
<cfreturn variables.thisStuff />
</cffunction>
test.cfm:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head>
<body>
<button type="button" id="testBtn" name="testBtn">Click Me</button>
<div id="testDiv"></div>
<script>
var testBtn = document.getElementById('testBtn'),
testDiv = document.getElementById('testDiv');
function testFunction(event,data){
testDiv.innerHTML = this.responseText;
}
testBtn.addEventListener('click',function(){
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", testFunction);
oReq.open("GET", "test.cfc?method=myTest1");
oReq.send();
});
</script>
</body>
</html>
This is what it returned:
Notice that even though I used the attribute returnFormat, it's not listed.
What happened here, Adobe? Shouldn't this have all attributes?
V/r,
^ _ ^
Copy link to clipboard
Copied
Thank you for all the suggestions. Really appreciate it.