A lot of sources call a single resource, typically through <cfthread ..>, but some use <cfinclude ..>.
Ideally, the code looks for the variable previous_state. If some variants are passed, then the resource will attempt to use them.
I received this error:
Variable PREVIOUS_STATE is undefined.
The line record points to the <cfif ..> in this chunk of code.
<cfparam name= "previous_state"
default= "" />
<cfif isSimpleValue( previous_state )
and len( previous_state ) eq 0>
<cfset previous_state= previousState />
</cfif>
My question is how can previous_state be undefined?
I can duplicate it in the application, but it's a fairly complex chain of code using threads. Perhaps the reference was eaten by the garbage collector?
I'm having trouble duplicating it in a simple code segment. I've tried setting the variable to the return of a function with returnType= "void", but <cfparam ..> seems to reset it to an empty string.
Here's the full code context. I removed the unrelated vars and such.
// Page
oComponent.foo();
// Component.foo()
<cfset var local= {
previous_state= QueryNew( "foo" , "varchar" )
} />
<cfthread name= "foo_#createUUID()#"
previousState= "#local.previous_state#">
<!--- Module does unrelated things... --->
<cfmodule template= "some_module.cfm">
<cfoutput>
// unrelated things
<cfparam name= "previous_state"
default= "" />
<!--- Next line is throwing error. --->
<cfif isSimpleValue( previous_state )
and len( previous_state ) eq 0>
<cfset previous_state= previousState />
</cfif>
</cfoutput>
</cfmodule>
</cfthread>
I'm now thinking cfparam is trying to use a scope that no longer exists by the time this code executes.
As the code is within a CFTHREAD tag I thing you should be passing previous_state as a CFTHREAD attribute, such as:
<cfparam name="previous_state" default="" />
<CFTHREAD previous_state = previous_state
previousState= "#local.previous_state#">
<cfif isSimpleValue( ATTRIBUTES.previous_state ) ........
</CFTHREAD>
To quote the CF Docs:
"The Attributes scope contains attributes that are passed to the scope, and is available only within the thread and only for the life of the thread."
For previous_state to be undefined it would need to be null. You would need to do something like
<cfif isNull(previous_state)>true</cfif>
To prove this try the following
<cfset previous_state = "" />
<!--- Change to set previous_state --->
<cfset previous_state = javacast( "null", previous_state ) />
<cfparam name="previous_state" default="" />
<cfif isSimpleValue( previous_state ) and len( previous_state ) eq 0 >
<cfset previous_state = previousState />
</cfif>
Make sure you scope your variables properly and your example above has a typo in it. I'm not having an issue running this code on both ACF9.0.1 and Railo 3.3.1.000
<cfparam name= "previous_state"
default= "" />
<cfdump var="#previous_state#">
Related
Does anyone know how I can forcibly stop a function execution in the cfc component if it works for more than a certain time? Either it may be piece of code, not a whole function, i.e. if it has completed in 5 seconds, I take some actions, otherwise others.
The only way to stop an arbitrary piece of code is to run it in a separate thread and then terminating after a set amount of time. This can be done by calling out to a separate page with a request timeout set or using cfthread.
For example with thread...
(Note.... as Alex pointed out you can use timeout on cfthread)
<cfthread action="run" name="runForLimitedTime">
... code, call to function, etc ...
</cfthread>
<cfset sleep(5000) />
<cfif cfthread.runForLimitedTime.status eq "COMPLETED">
<cfthread action="join" />
<cfelse>
<cfthread action="terminate" name="runForLimitedTime" />
</cfif>
Alternatively with a separate page...
<!--- calling page --->
<cfset error = false />
<cftry>
<cfhttp url="pageSetupForSpecificCall.cfm?timeout=5" throwonerror="true" />
<cfcatch>
<cfset error = true />
</cfcatch>
</cftry>
<cfif error>
something
<cfelse>
something else
</cfif>
<!--- pageSetupForSpecificCall.cfm --->
<cfsetting requesttimeout="#url.timeout#" />
...do things...
You can run this cftry gist with either the first or second indicated block of code uncommented to see the problem.
<cffunction name="alpha" returntype="boolean">
<cfargument name="boo" type="boolean" />
<cfreturn arguments.boo />
</cffunction>
<cffunction name="beta">
<cfset var temp = {} />
<cftry>
<cfset temp.userID = 1 />
<!--- This way throws an *unhandled* exception --->
<!--- --->
<cfif alpha(structAppend({userID = temp.userID}, foo))>
<cfdump var="It worked" />
</cfif>
<!--- This way works as expected --->
<!---
<cfset temp.args = {userID = temp.userID} />
<cfif alpha(structAppend(temp.args, foo))>
<cfdump var="It worked" />
</cfif>
--->
<cfcatch>
<cfdump var="#cfcatch.message#" />
</cfcatch>
</cftry>
</cffunction>
I know the struct literal notation {} will sometimes show generically named structs in my debugger, but why should assigning what's created by such syntax make the struct creation happen at a different time than if it's not assigned?
If I debug, I can set a breakpoint on the line where I set temp.userID = 1 and it skips right over it. Moreover, the exception is being thrown on a line contained in a try/catch, but it's failing to catch it.
I know in JavaScript there's the notion of 'hoisting'. I can only assume in some (but not all!) cases CF is doing something similar to struct literals.
Is this a bug, or a known behavior of CF?
<cfparam name="instance.params.sel_isCriteriaChanged" default="false">
Here instance is a global structure but "sel_isCriteriaChanged" inside that is created using form variable. But in certain form i dont have that variable. It'll be undefined in that case.
So in that case how to set the variable to false as default value.
I am using this variable inside CFC file
If I understand the question correctly you have something like this:
<cfparam name="instance.params.sel_isCriteriaChanged" default="false">
<cfset instance.params = {}>
<cfloop collection="#FORM#" item="key">
<cfset instance.params[key] = FORM[key]>
</cfloop>
but the cfparam gets overwriten here. Just make sure the form value is always defined:
<cfparam name="FORM.sel_isCriteriaChanged" default="false">
If I understand your problem correctly, you might do something like the following:
<cfset instance.params.sel_isCriteriaChanged = structKeyExists(form, "sel_isCriteriaChanged") ? form.sel_isCriteriaChanged : false />
This is shorthand for:
<cfif structKeyExists(form, "sel_isCriteriaChanged")>
<cfset instance.params.sel_isCriteriaChanged = form.sel_isCriteriaChanged />
<cfelse>
<cfset instance.params.sel_isCriteriaChanged = false />
</cfif>
I like the terseness of the ternary operator ? : and I try to avoid using <cfparam> if possible. Hope this helps.
I'm getting an issue as "Error Occurred While Processing Request
The system has attempted to use an undefined value, which usually
indicates a programming error, either in your code or some system code.
Null Pointers are another name for undefined values."
I verified all posts related to NPException & most of the issues are related to cfquery, cfhttp......This issue is with in cfloop iteration in cfc function (Y)
I have two functions X & Y. Y is called by X multiple times with in the loop. This loop is in cflock tag with timespan=5
function X :
============
<cfset Var array = getXML()>
<cfargument name="searchOnly" type="boolean" required="false">
<cfset Var i = "">
inside loop Y method is called
<cflock scope="Session" type="exclusive" timeout="5">
<cfloop from="1" to="#ArrayLen( array )#" index="i">
<cfset fields = Y( array[i], Arguments.searchOnly )>
</cfloop>
</cflock>
===========
function Y :
============
<cffunction name=“Y”>
<cfargument name="root" required="true">
<cfargument name="searchOnly" type="boolean" required="false">
<cfset Var i = "">
<cfloop index="i" from="1" to="#ArrayLen( Arguments.root.XMLChildren )#">
<cfset childNode = Arguments.root.XMLChildren[i]> ---> this line causes an error
<cfif Arguments.root.XMLName neq "match">
<!--- Recursive call --->
<cfset Y( labeledElements, Y( childNode ) )>
</cfif>
Is there any issue with Recursive call with in the same cfloop.
</cfloop>
</cffunction>
Variable i is declared in these two cffunctions, is this raising any issue with same variable name i. Please share your thoughts
You're not var-ing childNode, so you will be overwriting the outer call's variable with the recursive call's one. This will make the process unstable, and unsurprising that you get unexpected results / errors.
I imagine that's your problem.
With ColdFusion MX7 if we encounter an exception we send an email to the development team containing dumps of the various data scopes including the form structure.
This works great for debugging except in the case of an error when the user logs in. We end up getting the password printed out.
So, the question is, is there a way to modify the CFDUMP file so that it filters the password value out of the form object?
Naturally we could put it in the same code that sends the email, however it would be ideal to put it in the CFDUMP file so that we do not have to worry about it showing up in other spots.
I have located the CFDUMP file and it seems to be binary, so I'm guessing we can't do it.
You can copy the dump.cfm file to dumporiginal.cfm, and then make a new dump.cfm that calls dumporiginal.cfm.
<!---
So that it won't execute twice if you
have a closing slash (<cfdump ... />)
--->
<cfif thisTag.executionMode neq "start">
<cfexit method="exitTag" />
</cfif>
<!---
defaults for optional attributes, taken from the docs
http://livedocs.adobe.com/coldfusion/8/htmldocs/Tags_d-e_08.html
--->
<cfparam name="attributes.expand" default="yes" />
<cfparam name="attributes.format" default="html" />
<cfparam name="attributes.hide" default="all" />
<cfparam name="attributes.keys" default="9999" />
<cfparam name="attributes.label" default="" />
<cfparam name="attributes.metainfo" default="yes" />
<cfparam name="attributes.output" default="browser" />
<cfparam name="attributes.show" default="all" />
<cfparam name="attributes.showUDFs" default="yes" />
<cfparam name="attributes.top" default="9999" />
<!--- Hide the password, but store its value to put it back at the end --->
<cfif isStruct(attributes.var) and structKeyExists(attributes.var, 'password')>
<cfset originalPassword = attributes.var.password />
<cfset attributes.var.password = "{hidden by customized cfdump}"/>
</cfif>
<!---
Call the original cfdump.
Which attributes you pass depends on CF version.
--->
<cfswitch expression="#listFirst(server.coldfusion.productVersion)#">
<cfcase value="6">
<cfdumporiginal
var = "#attributes.var#"
expand = "#attributes.expand#"
hide = "#attributes.hide#"
label = "#attributes.label#"
>
</cfcase>
<cfcase value="7">
<cfdumporiginal
var = "#attributes.var#"
expand = "#attributes.expand#"
hide = "#attributes.hide#"
label = "#attributes.label#"
top = "#attributes.top#"
>
</cfcase>
<cfdefaultcase>
<cfdumporiginal
var = "#attributes.var#"
expand = "#attributes.expand#"
format = "#attributes.format#"
hide = "#attributes.hide#"
keys = "#attributes.keys#"
label = "#attributes.label#"
metainfo = "#attributes.metainfo#"
output = "#attributes.output#"
show = "#attributes.show#"
showUDFs = "#attributes.showUDFs#"
top = "#attributes.top#"
>
</cfdefaultcase>
</cfswitch>
<!--- Restore the password, in case it's read after cfdump call --->
<cfif isDefined("originalPassword")>
<cfset attributes.var.password = originalPassword />
</cfif>
No, I don't think there is a way to modify <cfdump>'s behavior. I can't be sure, obviously. It's thinkable that such a hack exists, though it's not necessarily recommendable.
Why not go with a simple:
<cftry>
<cfset DoSomethingThatFails()>
<cfcatch>
<cfif StructKeyExists(FORM, "Password")>
<cfset FORM.Password = "***">
</cfif>
<cfdump var="#FORM#">
</cfcatch>
</cftry>
CFDUMP began life as a custom tag (CF_DUMP) way back in the CF5 days. You could always get the code for that custom tag and modify it to your needs and use that instead of the built-in tag.
Is it only the password that is a problem of showing? If so, perhaps the solution is to salt/hash the password? That I think is good practice anyway.
http://blog.mxunit.org/2009/06/look-ma-no-password-secure-hashing-in.html