• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

error handling inside cfc

Participant ,
May 03, 2012 May 03, 2012

Copy link to clipboard

Copied

i have a cfgrid bound to a text field as well as a cfc

text field passes a value to cfc where it's being used as a parameter for a query . query can return zero records, when that happens, browser throws a json error

how can i trap this error inside the cfc and return a message to user? (without using a proxy)

thanks

TOPICS
Advanced techniques

Views

3.9K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Participant , May 07, 2012 May 07, 2012

well, some people would say it's crazy to work a full day on throwing an alert, and i tend to agree. Thanks everybody for suggestions, for what it's worth, this is how it works:

do NOT specify the onLoad event in cfgrid, do NOT use ajaxonload.

instead, create this js function, with THIS particular syntax:

getTotalApps = function() {

var isGrid = ColdFusion.Grid.getGridObject('myGrid');

var isData = isGrid.getStore();

isData.addListener("load",function() {

    if(isData.totalLength == 0)

        {

      

...

Votes

Translate

Translate
LEGEND ,
May 03, 2012 May 03, 2012

Copy link to clipboard

Copied

sounds like if/else 101 to me.  What would you like to happen if 0 records are applied.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
May 04, 2012 May 04, 2012

Copy link to clipboard

Copied

Thanks for answering,

i've tried the obvious <cfif myQuery.recordCount eq 0> No records found<cfabort><cfif>

however, looks like inside a cfc <cfabort> simply doesn't work, the cfc is trying to return the structure to the calling cfm anyway and the structure is empty, hence the json error

i've also tried (with same result)

  <cfif myQuery.recordCount eq 0>

    <script language="JavaScript">

       alert("No records found");

    </script>

  </cfif>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
May 04, 2012 May 04, 2012

Copy link to clipboard

Copied

i found the reason, the text field the grid is bound to is taking its values from an Oracle database, which is case sensitive. my query was matching the search param on lower(myColumn) on the WHERE clause, but didn't bother to do the same on the SELECT lower(myColumn). as a result, the value of the text field could have both upper and lower case chars, while the query could have only lower.

soon as i changed the qry to select lower(myColumn) where lower(myValue) the error went away

thanks

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
May 04, 2012 May 04, 2012

Copy link to clipboard

Copied

but i still didn't figure how to throw a "No records found" message for user

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 04, 2012 May 04, 2012

Copy link to clipboard

Copied

ion wrote:

but i still didn't figure how to throw a "No records found" message for user

<cffunction name="f" returntype="Any">

    <cftry>

    <cfquery name="myQuery">

    </cfquery>>

    <cfif myQuery.recordCount eq 0>

        <cfthrow message="Query returns no records">

        </cfif>

    <cfcatch type="any">

        <cfreturn cfcatch.message>

    </cfcatch>

    </cftry>>

</cffunction>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 04, 2012 May 04, 2012

Copy link to clipboard

Copied

Why are you going through the motions of raising an exception, only to catch it and then return the very message you threw in the first place?  Why don't you just return the message directly? What are you getting out of the try/throw/catch approach you're using here?

It might be fair enough to raise an exception in situations in which there are no records, but you shouldn't catch it in th same context you throw it (it defeats the purpose of using an exception in the first place), just let the exception bubble up to the calling code, and let that code decide what to do with it.

--

Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 04, 2012 May 04, 2012

Copy link to clipboard

Copied

Adam Cameron. wrote:

Why are you going through the motions of raising an exception, only to catch it and then return the very message you threw in the first place?  Why don't you just return the message directly? What are you getting out of the try/throw/catch approach you're using here?

It might be fair enough to raise an exception in situations in which there are no records, but you shouldn't catch it in th same context you throw it (it defeats the purpose of using an exception in the first place), just let the exception bubble up to the calling code, and let that code decide what to do with it.

I agree, and hope Ion will note this. I have assumed he might want to run more business code in the catch and/or to manage the return. To have the exception percolate up the call stack, one could do something like

<cffunction name="f" returntype="Any">

    <cfquery name="myQuery">

    </cfquery>

    <cfif myQuery.recordCount eq 0>

        <cfthrow message="Query returns no records">

     </cfif>   

</cffunction>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
May 06, 2012 May 06, 2012

Copy link to clipboard

Copied

thanks Adam, BKBK, but looks like cfthrow inside a cfc behaves like the other tags i've tried, i can't really control it

to my actual message, "No records found" it adds its own stuff that i don't want the users to see, like:

Error invoking CFC /.../mycfc.cfc: No records found [Enable debugging by adding 'cfdebug' to your URL parameters to see more information]

i've tried initializing all cfthrow attributes to blank, like: type = "any" detail = "" errorCode = ""  extendedInfo = ""

with same result.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 06, 2012 May 06, 2012

Copy link to clipboard

Copied

ion wrote:

looks like cfthrow inside a cfc behaves like the other tags i've tried, i can't really control it

Not necessarily. See my previous example.

However, note what Adam said. Throwing an exception is a powerful tool that should not be wasted on an example like this one. It would be preferable to just return the string "No records found".

But, you may ask, what if the function is engaged in some other business which requires it to, for example, return an array. Then you could make the function's returntype a struct. The struct would then contain an array and a string! It goes like this

<cffunction name="f" returntype="struct">

   <cfset var myReturnStruct = structNew()>

   <cfset myReturnStruct.values = arrayNew(1)>

   <cfset myReturnStruct.status = "">

  

    <cfquery name="myQuery">

    </cfquery>

    <cfif myQuery.recordCount eq 0>

       <cfset myReturnStruct.status = "Query returns no records">

        </cfif>

     <!--- Etc., etc., including business code that writes to the array myReturnStruct.values --->

  

     <cfreturn myReturnStruct>

</cffunction>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
May 07, 2012 May 07, 2012

Copy link to clipboard

Copied

thanks again BKBK, but there isn't any calling code, it's just a cfgrid bound to the cfc. i know i could turn it into a proxy and use the proxy to manipulate the grid (and the alert message), but this is simply too much work just to send a text message to the user, which is all i want

your suggestion, to insert the message into the returning struct from cfc won't work very well either, the message will appear inside the grid, and i don't want that

regards

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
May 07, 2012 May 07, 2012

Copy link to clipboard

Copied

kind of half of a solution i found, is to attached a js function to the onLoad event of the grid, on the caller page, like:

getTotalApps = function(){

var isGrid = ColdFusion.Grid.getGridObject('myGrid');

var isData = isGrid.getStore().totalLength;

if (isData == 0) {alert("No records found"}

}

however, this only works the first time page is loaded, not every time the grid changes, and since the onChange event is already occupied by the cfc, i can't put it there

i was NEVER able to make <cfset ajaxonload("getTotalApps")> to work in ie8. if i put javascript within <head></head> tags, it renders a blank page with error "DOM is null or not an object"

if i remove the <head>, function doesn't get executed

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 07, 2012 May 07, 2012

Copy link to clipboard

Copied

ion wrote:

kind of half of a solution i found, is to attached a js function to the onLoad event of the grid, on the caller page, like:

getTotalApps = function(){

var isGrid = ColdFusion.Grid.getGridObject('myGrid');

var isData = isGrid.getStore().totalLength;

if (isData == 0) {alert("No records found"}

}

however, this only works the first time page is loaded, not every time the grid changes, and since the onChange event is already occupied by the cfc, i can't put it there

i was NEVER able to make <cfset ajaxonload("getTotalApps")> to work in ie8. if i put javascript within <head></head> tags, it renders a blank page with error "DOM is null or not an object"

if i remove the <head>, function doesn't get executed

Everything points to one of the simplest solutions possible, namely:

<cffunction name="f" returntype="string">

<cfset var message = "">

<cfquery name="myQuery">

</cfquery>

<cfif myQuery.recordCount eq 0>

<cfset message = "No records found">

<cfelse>

<cfset message = myQuery.recordCount & " record(s) found">

</cfif>

<cfreturn message>

</cffunction>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
May 07, 2012 May 07, 2012

Copy link to clipboard

Copied

BKBK, the cfc is bound to a grid so it must return a structure. you can't change returntype on the fly

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 07, 2012 May 07, 2012

Copy link to clipboard

Copied

LATEST

ion wrote:

BKBK, the cfc is bound to a grid so it must return a structure. you can't change returntype on the fly

Please ignore. I posted that without realizing you already had an answer.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 07, 2012 May 07, 2012

Copy link to clipboard

Copied

there isn't any calling code, it's just a cfgrid bound to the cfc.

Ah, sorry: I came into this late and didn't read the earlier posts.

<cfgrid> has an onerror handler for when - I presume - a bind operation fails.  Does this not give you what you want?  The JS function can do anything, after all.

Reading here:

http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec22c24-7a01.html...

That said, I dunno how to send the message back from the server, but in this case perhaps you don't: you're just trying to pass back a hard-coded string if you get an error, so why not simply hard-code the message in the <cfgrid> code?

I've never used this functionality before, so I'm pretty vague on how it works... if it sounds like it'll work, then perhaps google about a bit.  Or maybe someone else here is au fait with how it all comes together..?

--

Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
May 07, 2012 May 07, 2012

Copy link to clipboard

Copied

well, some people would say it's crazy to work a full day on throwing an alert, and i tend to agree. Thanks everybody for suggestions, for what it's worth, this is how it works:

do NOT specify the onLoad event in cfgrid, do NOT use ajaxonload.

instead, create this js function, with THIS particular syntax:

getTotalApps = function() {

var isGrid = ColdFusion.Grid.getGridObject('myGrid');

var isData = isGrid.getStore();

isData.addListener("load",function() {

    if(isData.totalLength == 0)

        {

          alert("No records found");

          return false;

        }

    });

}

ColdFusion.Event.registerOnLoad(getTotalApps,null,false,true);

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation