1

So, I have allmost spend the night chasing a bug.... found it and no idea what is wrong.

I have script in Coldfusion which sends two emails. Both mails are in a mailer script which I'm calling with cfinvoke like so:

<cfinvoke component="form_mailer_basket" method="msg_order_seller"> 
... parameters
</cfinvoke>

<cfinvoke component="form_mailer_basket" method="msg_order_retailer">
... parameters
</cfinvoke>

Both mail parameters are all ok, but the 2nd mailer throws an error:

mailer orders 
************************************************************************************ 

type: Application 
************************************************************************************ 

message: Could not find the ColdFusion Component or Interface form_mailer_basket. 
************************************************************************************ 

detail: Ensure that the name is correct and that the component or interface exists. 
************************************************************************************ 

Question:
Can anyone tell me why the 2nd mail cannot find the component when the first script 5 lines above can?

Thanks!

EDIT:
Here is my code for calling both methods:

<cfif new_mail.recordcount GT 0>
    <cfloop query="new_mail">
        <cfset variables.newMail = new_mail.email_bestelleingang>
            <cfinvoke component="form_mailer_basket" method="msg_order_seller"> 
                <cfinvokeargument name="delDate" value="#variables.liefdatum_mail#"/>
                <cfinvokeargument name="delMsg" value="#variables.bestell_text_mail#"/>
                <cfinvokeargument name="delOrd" value="#LOCAL.Basket.bestelltyp#"/>
                <cfinvokeargument name="mailto" value="#variables.newMail#"/>
                <cfinvokeargument name="client" value="#LOCAL.Basket.re_firma#"/>
                <cfinvokeargument name="rebate" value="#variables.kopf_rabatt#"/>
                <cfinvokeargument name="sellerIln" value="#variables.iln_verkaeuferNEU#"/>
                <cfinvokeargument name="ordNo" value="#variables.bestellnummer_neu#"/>
            </cfinvoke> 
    </cfloop>
</cfif>

...

 <cfloop query="active_check">
      <cfif active_check.freigeschaltet NEQ "1" AND active_check.freigeschaltet NEQ "0">
           <cfinvoke component="form_mailer_basket" method="msg_order_retailer">
                <cfinvokeargument name="delDate" value="#variables.liefdatum_mail#" />
                <cfinvokeargument name="delOrd" value="#LOCAL.Basket.bestelltyp#" />
                <cfinvokeargument name="mailto" value="#variables.cusMail#" />
                <cfinvokeargument name="client" value="#order_recipients.firma#" />
                <cfinvokeargument name="rebate" value="#variables.kopf_rabatt#" />
                <cfinvokeargument name="sellerIln" value="#variables.iln_verkaeuferNEU#" />
                <cfinvokeargument name="ordNo" value="#variables.bestellnummer_neu#" />
                <cfinvokeargument name="total" value="#variables.gesamtsumme#" />
                <cfinvokeargument name="menge" value="#variables.gesamtmenge#" />
                <cfinvokeargument name="curr" value="#variables.waehrung#" />
                <cfinvokeargument name="agentF" value="#variables.agentFirma#" />
               <cfinvokeargument name="agentN" value="#variables.agentName#" />
            </cfinvoke>
         </cfif>
    </cfloop>

First one works, second one doesn't. Method names are correct, all parameters are ok (I know I should use an argumentsColletion...), so I'm clueless and need to take a nap. Checking back later!

And the cfc:

<cfcomponent output="false" hint="basket mailing cfc - sends out all basket related mail messages">

    <!--- LOAD LANGUAGES --->
    <cfinclude template="../templates/tmp_lang.cfm">

    <!--- INIT --->
    <cffunction name="Init" access="public" returntype="any" output="false" hint="Initialize">

        <!--- nothing here for now --->

        <cfreturn true />
    </cffunction>

    ... msgs like this:

    <!--- NEW ORDER SELLER --->
    <cffunction name="msg_order_seller" access="public" output="false" hint="msg for new orders"> 
        <cfargument name="delDate" type="date" required="true" hint="delivery date" />
        <cfargument name="delMsg" type="string" required="true" hint="text message by retailer" />
        <cfargument name="delOrd" type="string" required="true" hint="order type pre/asap" />
        <cfargument name="mailto" type="string" required="true" hint="email adress" />
        <cfargument name="client" type="string" required="true" hint="buyer" />
        <cfargument name="rebate" type="string" required="true" hint="rebate 1/0" />
        <cfargument name="sellerIln" type="string" required="true" hint="seller ILN" />
        <cfargument name="ordNo" type="string" required="true" hint="order number" />

        <cfprocessingdirective suppresswhitespace="No">
            <cfmail
                    TO="#mailto#"
                    FROM="automailer@..."
                    SERVER="mail.bbb.de"
                    USERNAME="ddd"
                    PASSWORD="123456"
                    SUBJECT="#tx_automailer_order_new# - #client#">
#tx_automailer_default_anrede#

#tx_automailer_order_info#

#tx_automailer_order_type#: #ordertype# #rebateTxt#
#tx_automailer_order_del#: #deliveryDate#

#tx_automailer_order_no#:     #ordNo#
#tx_automailer_order_date#:      #DateFormat(now(),"dd.Mm.yyyy")#

#tx_kaeufer#:            #client#
#tx_automailer_order_msg#:
#delMsg#

#tx_automailer_order_iln#:  #sellerIln#

#tx_automailer_default_gruss#
#tx_automailer_default_team#
-------------
#tx_automailer_default_disclaimer#
                    </cfmail>
              </cfprocessingdirective>      
          <cfreturn />
    </cffunction>  
    ...

 </cfcomponent>     
frequent
  • 27,643
  • 59
  • 181
  • 333
  • Can you call the "msg_order_retailer" method on it's own and does it work? Trying to determine if the issue is with the method itself or truly a product of the other processing. Does the "msg_order_retailer" method ever work? – Miguel-F Nov 21 '12 at 13:28

3 Answers3

3

If you just want to solve your problem instead of trying to figure out what is causing it, I have a suggestion. Instead of using the cfinvoke tag for the same component many times, use either cfobject or CreateObject() to make just one instance of it. Then call the methods directly.

Even if you do get your current approach to work, it will be slower than my suggestion. cfinvoke creates an object each time you call it and that takes processing time.

Dan Bracuk
  • 20,699
  • 4
  • 26
  • 43
  • so this object will then be available to the user/session? i'm usually using cfinvoke, but it does make sense to maybe have an object here. need to check – frequent Nov 21 '12 at 15:04
  • That depends on where you store the object. If you store it in a persistant, global scope (eg: application or session), that single object (generally referred to as a 'singleton') will be accessible throughout your app without needing to recreate it. If you just do a simple createObject without adding it to a scope, it will just be accessible throughout the page you are processing. Both are more efficient than multiple cfinvokes. – Joe C Nov 21 '12 at 16:07
  • To add on to what @phantom42 was saying, essentially you can set your components (objects) to any variable scope and call them accordingly. This is nice because for functions that get called all the time, they can be set in something like application scope and initialized only once. Additionally, because cfinvoke has to load the whole component every time it's called, assuming that all the functions did exist in your component, your issue above may have been memory related because of the loops + cfinvoke. – Sharondio Nov 21 '12 at 18:14
  • the object will be available to the session scope if you set it to a session variable, such as session.myObject. Be careful about what you put in the session scope. With today's browsers, all tabs share the same session. This allows users to inadvertently change session variables. It's happened to us. – Dan Bracuk Nov 22 '12 at 16:11
2

Are you sure that both methods exist and are public?

Paul
  • 1,577
  • 7
  • 10
1
  1. Using cfinclude in cfc is NOT good practice, though admittedly I had to do it too on occasions.
  2. Your error Could not find the ColdFusion Component or Interface form_mailer_basket seems to imply that something happens to the component itself - I suspect it has something to do with your return statement in Init() method.
  3. In earlier versions of CF (I think around version 6/7 maybe 8) you could overwrite your function by setting identically named variable inside your cfc. You did not mention the CF version that you are running.
Community
  • 1
  • 1
Germann Arlington
  • 3,315
  • 2
  • 17
  • 19
  • oh. good point. CF8 it is. Regarding cfc use, my question and comments got me thinking. My whole system is set up in cfc, so I'm stuck having to cfinclude sometimes. Usually when I'm breaking another convention by generating html output inside a cfc. I'm doing it here, because the cfc is generating email messages, which need to be available in multiple languages, hence I need to pull the texts in the respective language from the database, which is done in the cfinclude. Curious to know how you would do something like this then = where should the email message be generated? Thanks! – frequent Nov 23 '12 at 11:58
  • 1
    Instead of using cfinclude in cfc you can extend language (or other) component(s) or pass them (instantiated objects) as parameter(s) to Init() method and use thier methods in your cfc. When generating content you can generate and return string (use `` inside the cfc methods to make it easier). – Germann Arlington Nov 23 '12 at 12:44
  • `cfsavecontent` I'm using, but I did not know about passing the language through the init call. Good idea. Thanks! – frequent Nov 23 '12 at 13:05