I'm doing a cffile upload, and want to trap any errors in the MIME type. I wrote this code:
<form
enctype= "multipart/form-data"
method = "post"
name = "templupload"
action = "frag2.cfm">
<cftry>
<cffile action = "upload"
destination = "#session.exploc#"
fileField = "form.theupload"
mode = '666'
accept = 'html'
strict = 'true'
result = 'ss'
nameConflict = "Overwrite">
<!--- bad mime type files --->
<cfcatch type = 'any'>
<cfif FindNoCase("The MIME type or the Extension of the uploaded file", cfcatch.message)>
<cfoutput>
<script>
document.getElementById('tmpl').innerHTML = "error";
</script>
</cfoutput>
</cfif>
</cfcatch>
<cfthrow type="any" message="got an error" />
</cftry>
When I try to upload a wrong MIME type, it does not load, which is good. The form is submitting which is not good but I'll deal with that later. My problem now is I have been unable to get a message about the error to show up anywhere. I have tried the following:
<cfcatch.message = 'error';
<script>alert('error');</script>
<script> document.getElementById('tmpl').innerHTML = "error";</script>
<!--- this 2nd script does not work regardless of whether the tmpl
id is on the original page or the target page --->
<cfoutput> error </cfoutput>
<p> error </p>
<cfthrow type = 'any' message = 'error' />
<cfdump var = "#catch#" or var = '#catch.message#"
I have tried all these inside and outside of the cfcatch tag, but always within the cftry tag. All of these approaches were in the research I did, but none of them are working for me.
Can anyone tell me what I am doing wrong here?
Are you looking for something like this?
<cftry>
<cfcatch>
<cfset request.error = cfcatch.message>
<cfcatch>
</cftry>
Then much much later
<cfif request.keyExists('error')>
<cfoutput>#request.error#</cfoutput>
</cfif>
Related
I'm in the process of trying to convert an old CF script. The only problem is I am using CommandBox and I can't seem to get Fiddler to show me what this request looks like when it's actually posted. Does anyone know what the Post request this sends out would look like?
I've tried a variety of options so far and nothing has worked.
Any help would be appreciated
<!---
Cold Fusion 4.0.1
--->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head></head>
<body>
<cfif isdefined("Form.thisid")>
<!--- Input Form Parameters --->
<cfset InputPbn = Form.thisid>
<cfoutput>
<h1>Raw XML data for #thisid#</h1>
</cfoutput>
<cfelse>
<h1>A valid thisid was not provided</h1>
<cfabort>
</cfif>
<!--- Assemble the user's input into structure --->
<CFSCRIPT>
// New request structure to pass
Request = StructNew();
Request.thisid = "#Inputthisid#";
host_url = "http://myurl/get_info_wddx.cfm";
Request["LINK_KEY"] = "1234";
</CFSCRIPT>
<!--- Convert the structure to WDDX Packet --->
<CFWDDX
INPUT="#Request#"
OUTPUT="RequestAsWDDX"
ACTION="CFML2WDDX"
>
<cfoutput>RequestAsWDDX #HTMLEditFormat(RequestAsWDDX)#<br/></cfoutput>
<!--- Post the WDDX Packet to the host page as a form field --->
<CFTRY>
<CFHTTP URL="#host_url#" METHOD="POST">
<CFHTTPPARAM
NAME="WDDXContent"
VALUE="#RequestAsWDDX#"
TYPE="FORMFIELD"
>
</CFHTTP>
<CFCATCH TYPE="Any">
WDDX - HTTP Error<BR>
<CFOUTPUT>#HTMLEditFormat(CFHTTP.FileContent)#</CFOUTPUT><BR>
<CFABORT>
</CFCATCH>
</CFTRY>
<!--- Extract recordset from WDDX Packet in host's response --->
<cfif FindNoCase("<META",CFHTTP.FileContent) >
<cfset pos = FindNoCase(">",CFHTTP.FileContent)>
<cfset wddx_strg = Right(CFHTTP.FileContent,(Len(CFHTTP.FileContent)-pos-1))>
<cfelse>
<cfset wddx_strg = CFHTTP.FileContent>
</cfif>
...
</body>
</html>
I was severely overcomplicating this ha, just had to use "WDDXContent" as the Key and the WDDXContent value as the value.
Edit: I have no code for this at this point, just was able to get fiddler to reproduce it by adding a header key "WDDXContent" and value
<wddxPacket version='1.0'><header/><data><struct><var name='link_key'><string>1234</string></var><var name='id'><string>[id here]</string></var></struct></data></wddxPacket>
I am working with ColdFusion and am new to the language. I want to perform a database operation with the given value and return the result via ajax response, when the onBlur event of a textbox is triggered. Please check my code below
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("#username").blur(function() {
alert("This input field has lost its focus.");
var userNameVal = $(this).val();
if(userNameVal != "") {
$.get("myajax.cfc?method=getuser&userName=userNameVal", function(res) {
$("#userid").val=res;
}, "JSON");
}
});
});
</script>
<input type='textbox' name='username' id='username' />
<input type='hidden' name='userid' id='userid'/>
myajax.cfc:
<cfcomponent>
<cffunction name="getuser" access="remote" returntype="Integer">
<cfargument name="userName" type="string" required="yes">
<cftry>
<cfquery name="getUser" datasource="ajax_example">
select USER_ID
from user u
where u.firstname=userName;
<cfqueryparam value = "#url.userName#" cfsqltype="cf_sql_varchar">
</cfquery>
<cfcatch>
<cfoutput>
#cfcatch.Detail#<br />
#cfcatch.Message#<br />
#cfcatch.tagcontext[1].line#:#cfcatch.tagcontext[1].template#
</cfoutput>
</cfcatch>
</cftry>
<cfreturn getUser.USER_ID/>
</cffunction>
</cfcomponent>
From my ajax.cfc response I want to return USER_ID to my ajax call. How can I do this?
You need to pass the actual value of the variable named userNameVal in the query string. Like this:
$.get("myajax.cfc?method=getuser&userName="+userNameVal, function(res) {
$("#userid").val=res;
}, "JSON");
And as #Dan suggested, the way you are using cfqueryparam, is wrong. It should be done like this:
<cfquery name="getUser" datasource="ajax_example">
select USER_ID
from user u
where u.firstname=<cfqueryparam value = "#arguments.userName#" cfsqltype="cf_sql_varchar">
</cfquery>
You have this code:
where u.firstname=userName;
<cfqueryparam value = "#url.userName#" cfsqltype="cf_sql_varchar">
This is not valid sql. The semi-colon terminates the command and ColdFusion will throw an error because the cfqueryparam tag comes afterwards.
You also have this query in a cftry block. The cfcatch code outputs data. If you were calling this function from ColdFusion code, you would see the cfcatch information in your web browser. However, you are calling it with ajax. It's outputting to a black hole. Also, you are getting no ColdFusion error because of the try/catch. Plus the cfcatch block does not include a cfreturn tag so nothing gets returned to javascript.
Another error is that you are using the wrong scope in your query. This:
value = "#url.userName#"
should be this:
value = "#arguments.userName#"
You are attempting to do too many things at once. I suggest calling your method with ColdFusion until you get it working properly. Then call it with ajax.
I have a form where I can upload logos a plenty. I'm validating files (empty form fields, wrong extension, ...) inside a cftry/cfcatch statement.
When I find an error in the cftry, I do this:
<cfthrow type="FileNotFound" message="#tx_settings_app_error_create_first#" />
and inside my 'cfcatch'
<cfcatch>
<cfoutput><script type="text/javascript">window.onload = function(){alert("#cfcatch.message#");window.location.href="hs_apps.cfm"; } </script></cfoutput>
</cfcatch>
This works fine, catches all errors and alerts the user what is wrong.
Now I wanted to use the same handler on a database call where I'm checking for duplicate username. Still the same:
<cfquery datasource="#Session.datasource#" name="duplicates">
SELECT a.app_alias
FROM apps AS a
WHERE a.iln = <cfqueryparam value = "#Session.loginID#" cfsqltype="cf_sql_varchar" maxlength="13">
AND a.app_alias = <cfqueryparam value = "#form.app_basic_alias#" cfsqltype="cf_sql_varchar" maxlength="50">
</cfquery>
<cfif duplicates.recordcount GT 0>
<cfthrow type="FileNotFound" message="#tx_settings_apps_error_dup#" />
</cfif>
The cfcatch is also the same.
However. This now procudes a server error page and I'm thrown out of the application.
Question:
Any idea, why I'm struggling to get cftry/cfcatch to work here? I'm clueless.
Thanks!
EDIT:
Here is the full code
<cfif isDefined("send_basic")>
<cfset variables.timestamp = now()>
<cfset variables.orderview = "1">
<cfif form.send_basic_type EQ "new">
<cftry>
<cfif module_check.recordcount GT 0>
<cfloop query="module_check">
<cfif module_check.module_name EQ "preorder">
<cfset variables.module_name = module_check.module_name>
<cfset variables.b2b_preord_ok = "true">
</cfif>
</cfloop>
<cfif form.app_basic_orderview EQ "preo">
<cfset variables.orderview = "0">
</cfif>
</cfif>
<!--- PROBLEM HERE: DUPLICATES --->
<cfquery datasource="#Session.datasource#" name="duplicates">
SELECT a.app_alias
FROM apps AS a
WHERE a.iln = <cfqueryparam value = "#Session.loginID#" cfsqltype="cf_sql_varchar" maxlength="13">
AND a.app_alias = <cfqueryparam value = "#form.app_basic_alias#" cfsqltype="cf_sql_varchar" maxlength="50">
</cfquery>
<cfif duplicates.recordcount GT 0>
<cfthrow type="FileNotFound" message="#tx_settings_apps_error_dup#" />
</cfif>
<!--- IF PASS, CREATE/UPDATE --->
<cfquery datasource="#Session.datasource#">
INSERT INTO apps ( ... )
VALUES( ... )
</cfquery>
<cfset variables.app_action = "Applikation erstellt">
<!--- success --->
<cfoutput><script type="text/javascript">window.onload = function(){alert("#tx_settings_app_cfm_create#");}</script></cfoutput>
<cfcatch>
<cfoutput><script type="text/javascript">window.onload = function(){alert("#tx_settings_app_err_create#");}</script></cfoutput>
</cfcatch>
</cftry>
<cfelse>
<cftry>
<!--- UPDATE --->
<cfquery datasource="#Session.datasource#">
UPDATE apps
SET ... = ...
</cfquery>
<cfset variables.app_action = "Applikation aktualisiert">
<!--- success --->
<cfoutput><script type="text/javascript">window.onload = function(){alert("#tx_settings_app_cfm_update#");}</script></cfoutput>
<cfcatch>
<cfoutput><script type="text/javascript">window.onload = function(){alert("#tx_settings_app_err_update#");}</script></cfoutput>
</cfcatch>
</cftry>
</cfif>
</cfif>
The error message I'm getting it the message I specify =
<cfthrow type="FileNotFound" message="#tx_settings_apps_error_dup#" />
Which if caught should alert the text behind tx_settings_apps_error_dup. If I dump the cfcatch, cfcatch.message is my specified text, so the error gets caught allright, only I get a server error page vs. an alert. I'm using exactly the same handler for fileuploads and form submits. I don't get why it's not working here?
Thanks for helping out!
WORKAROUD:
Note nice, but suffice(s):
<cfif dups.recordcount NEQ 0>
<cfoutput><script type="text/javascript">window.onload = function(){alert("#tx_settings_apps_error_dup#"); location.href = "hs_apps_detail.cfm?create=newApp&id=none";}</script
</cfoutput>
<cfabort>
</cfif>
So when a duplicate is found I alert the user, reload the exact same page and cfabort to prevent the old page from processing further. Patch that is.
(moved this down from being just a comment)
OK, so the catch is definitely catching the exception if you're able to dump it, so it's not that the try/catch ain't working, it's something else. Bear in mind that processing will continue until the end of the request after your catch block, and only then will the output buffer be flushed, and your alert() sent to the browser. It sounds to me like after your output the alert, and processing continues, some OTHER error is occurring which is causing the server's error page to display. I recommend getting rid of the error page temporarily and eyeballing the actual error CF is raising.
NB: if you want processing to stop immediately in the catch block after you output the alert(), you're going to need to tell CF that, ie: with a <cfabort>. Otherwise, as per above, it'll just keep going.
I think exceptions that are caught by the server error page are still logged in the exception log, but I could be wrong. You could always put an onError() handler in your Application.cfc, log whatever error occurred, then rethrow the error so the error page still deals with it. That way you get the info on the error, and the punter still sees the nice error page.
cffile is giving a head ache now.
My cfm is like this -
`
<cfif session.ismac and session.browsermake eq "firefox">
<cfset size = "55">
</cfif>
<cfset onChange = "document.frmMain.submit1.disabled = true;setdisplayname(this,this.form.dummy);">
<cfif displayname EQ "">
<cfset size = "document.frmMain.submit1.disabled = true;setdisplayname(this,this.form.displayname);">
</cfif>
<cfinput type="file" name="File#thisUploader#" id="File#thisUploader#" size="#size#" onKeyPress="return false;" onchange="#onChange#">
`
and in my cfc the code is like this -
<cffile accept="image/*" action="upload" destination="#application.artworkfilepath#\bulkuploads\#session.loginname#\#form.category#\" filefield="form.File#thisUploader#" nameconflict="makeunique">
and if I dump - <cfoutput>
You uploaded #cffile.ClientFileName#.#cffile.ClientFileExt#
successfully to #cffile.ServerDirectory#.
</cfoutput>
<cfabort>
I get corrct things and no error.
But when i look into the folder there is nothing.
Anyidea? I have added the dump of cffile now. What do you make out of it?
cfform code is like this <cfform id="frmMain" name="frmMain" action="process_multi.cfm" enctype="multipart/form-data" target="_self" method="post">
do a fileExists() directly after the statement and let us know what that says...
you don't have a directorywatcher on the directory do you?
Your cffile nameconfict attribute is set to makeunique, which tells ColdFusion to rename the file to something new when it arrives at the server--if the file already exists.
However, you are using cffile.ClientFileName and cffile.ClientFileExt to refer to the file file--which maps to the unchanged file name as it was received during upload.
Change your code references to cffile.ServerFileName and cffile.ServerFileExt for the final renamed result.
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