I am trying to put the filename of a failed upload into an email, inside a try / catch, but I am not having any luck.
Based on this documentation - FileUploadAll() - I decided I am going to use error.
<cftry>
<cffile destination="#FULLPATH#" action="upload" nameconflict="ERROR" continueOnError="true" filefield="FileName" />
<cfcatch type="Any" >
<cf_EmailHandler from="testmail#gmail.com" to="testmail#gmail.com" subject="Attachment Error - #BUILD_SEARCH.PROJECT_VERSION# #BUILD_SEARCH.BUILD_NUMBER#">
<CFOUTPUT>
Attachment Error - #BUILD_SEARCH.PROJECT_VERSION# #BUILD_SEARCH.BUILD_NUMBER#
Cannot upload the following file:
#FULLPATH# #ArrayLen(cffile.uploadAllErrors)#
</CFOUTPUT>
</cf_EmailHandler>
<b>Error:</b>File already exists.
<cfabort>
</cfcatch>
</cftry>
I get the following error:
Element UPLOADALLERRORS is undefined in CFFILE
So I try to fix that:
<cftry>
<cffile destination="#FULLPATH#" action="upload" nameconflict="ERROR" Errors="errorResult" continueOnError="true" filefield="FileName" />
<cfcatch type="Any" >
<cf_EmailHandler from="testmail#gmail.com" to="testmail#gmail.com" subject="Attachment Error - #BUILD_SEARCH.PROJECT_VERSION# #BUILD_SEARCH.BUILD_NUMBER#">
<CFOUTPUT>
Attachment Error - #BUILD_SEARCH.PROJECT_VERSION# #BUILD_SEARCH.BUILD_NUMBER#
Cannot upload the following file:
#FULLPATH# #ArrayLen(errorResult.uploadAllErrors)#
</CFOUTPUT>
</cf_EmailHandler>
<b>Error:</b>File already exists.
<cfabort>
</cfcatch>
</cftry>
Then I am getting:
Element UPLOADALLERRORS is undefined in ERRORRESULT.
Any idea on what I am doing wrong or another way to display the name of failed upload? Also I am using ColdFusion 11.
Update:
Bug report CF-4204290 currently lists this issue as "To Fix".
TL;DR;
It's a documentation bug. The continueOnError attribute isn't supported with action=upload. Use action=uploadAll instead. Keep in mind "uploadAll" supports multiple files, so results will be returned as an array of structures.
The reason it's not working is because the code is using the wrong "action". It should be action="uploadAll". Since you're using continueOnError="true", CF populates a structure with any errors that occur. By default it uses CFFILE, but you can specify a different variable name by using the errors attribute.
<cffile destination="c:/some/path/"
action="uploadAll"
nameconflict="ERROR"
continueOnError="true"
filefield="file_path" />
Update:
As pointed out in the comments, the documentation does saycontinueOnError is a supported attribute for action=upload. However, IMO it's a documentation bug. Adobe probably just copied the text from the action=uploadAll description.
Interestingly, the documentation for FileUpload(), doesn't list that attribute at all. Bug report CF-4199503 confirms the function version doesn't support it. Based on my tests below with CF11 and CF2016, I've concluded it's not supported in either version.
Test Action=UploadAll
Uploading a file that already exists in the destination directory, doesn't cause a hard error. CF populates the specified variable with error details and dumps them on screen:
<cfif structKeyExists(FORM, "submit")>
<cffile destination="c:/temp"
action="uploadAll"
nameconflict="ERROR"
continueOnError="true"
errors="myErrors"
filefield="file_path" />
<cfdump var="#cffile#" label="cffile">
<cfdump var="#myErrors#" label="errors">
</cfif>
<form method="POST"
enctype="multipart/form-data">
<input type="file" name="file_path">
<input type="submit" name="test">
</form>
Results:
Test Action=Upload
Change the action to action="upload" and the code fails. ColdFusion does NOT:
Continue processing after the error .. or
Populate cffile with error information ... or
Create a result variable named by the errors attribute
Results:
Note, omitting the optional errors attribute produces the same results. It works as expected when using action=uploadAll and fails with an error when using action=upload
In the form page, I captured the filename using JavaScript
<Input Name="FileName" type="file" size="#TEXT_AREA_WIDTH#"><br><br>
<Input type="Hidden" id="READ_FILE_NAME" name="READ_FILE_NAME" value="">
<Input type="Submit" name="Operation" value="Save" onclick="return validateAttachmentForm(this.form.FileName.value)">
function validateAttachmentForm(file_name)
{
if (file_name.lastIndexOf("\\" != -1)) {
var file_name = file_name.substring(file_name.lastIndexOf("\\") + 1, file_name.length);
}
document.getElementById("READ_FILE_NAME").value = file_name;
if(file_name != "")
{
return true;
} else{
alert('Please select a file to upload.')
return false;
}
}
In the next page, I just display the filname passed in
<cftry>
<cffile destination="#FULLPATH#" action="upload" nameconflict="ERROR" Errors="errorResult" continueOnError="true" filefield="FileName" />
<cfcatch type="Any" >
<cf_EmailHandler from="testmail#gmail.com" to="testmail#gmail.com" subject="Attachment Error - #BUILD_SEARCH.PROJECT_VERSION# #BUILD_SEARCH.BUILD_NUMBER#">
<CFOUTPUT>
Attachment Error - #BUILD_SEARCH.PROJECT_VERSION# #BUILD_SEARCH.BUILD_NUMBER#
Cannot upload the following file:
#FULLPATH#\#form.READ_FILE_NAME#
</CFOUTPUT>
</cf_EmailHandler>
<b>Error:</b>File already exists.
<cfabort>
</cfcatch>
</cftry>
Related
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>
i'm working on my legacy system old code of coldfusion, is there a way i can define cfcatch in application.cfc and catch all errors of my application with
Function name
Query name
Line Number of code
Template Name
To debug fast rather then writing everywhere in code.
application developer did not catch any error anywhere in code.i did insert cfcatch in code some of the places but still lot more to do, and because of production i don't want to modify so much of code.
im inserting cfcatch in databse and sending email to development team. because system is in production.
You can use the cferror tag, or onError to direct all errors to a given page/function.
If you use cferror, the exception will be passed in the error variable. If you use OnError, it's a parameter.
To help you along, my own error emails include the following. You will notice that we have special handling to help point out places where a blank may have been passed into a sql integer field, which happens more often than I'd like to admit.
An error occurred: http://#cgi.server_name##cgi.script_name#?#cgi.query_string#<br />
Time: #dateFormat(now(), "short")# #timeFormat(now(), "short")#<br />
<!--- Smarter error catching for form fields --->
<cfif (error.message contains "Invalid data '' for CFSQLTYPE CF_SQL_INTEGER") and isdefined("form")>
<!--- This stores a list of the Id fields --->
<cfloop collection="#form#" item="thisField">
<!--- Get the last two characters of the field name --->
<cfset lastTwoChars = right(thisField, 2)>
<!--- Get the value of the field --->
<cfset thisFieldValue = evaluate('form.#thisField#')>
<!--- Check to see if this is an Id field and if it's value is blank. --->
<cfif lastTwoChars eq 'Id' and thisFieldValue eq ''>
<h3 style="font-weight: bold; color: red">#thisField# is blank and it's possibly an integer field.</h3>
</cfif>
</cfloop>
</cfif>
<cfdump var="#error#" label="Error">
<br/>
<cfdump var="#form#" label="Form">
<br/>
<cfdump var="#url#" label="URL">
<br/>
<cfdump var="#session#" label="session">
I have a page that prints an array with some information to the screen from a session variable (session.stufailedarray). At the top of the page, there a link to export the information to excel. When I try this (in Firefox, IE and Chrome) it works fine. But users keep telling me that they're receiving an error message: "Element stufailarray is undefined is session". I know the variable is there because it just printed it to the screen and I can see it in the debugging. Why would this be happening and only sometimes?
Code that generates error:
<cfset ind=0>
<cfset anArray=arrayNew(2)>
<cfloop array="#session.stufailarray#" index="k">
<cfset ind+=1>
<cfset session.failed=find("UPDATE FAILED: ", "#k#")>
<cfset session.rrr=REFind("\d{9,9}", "#k#")>
<cfset idno=mid("#k#", REFind("\d{9,9}", "#k#"), 9)>
<cfset failed=mid("#k#", Refind("UPDATE FAILED: ", "#k#"), Len(#k#)-(Refind("UPDATE FAILED: ", "#k#")))>
<cfset anArray[ind][1]=#idno#>
<cfset anArray[ind][2]=#failed#>
</cfloop>
<!--- Set content type. --->
<cfcontent type="Application/vnd.ms-excel">
<cfheader name="Content-Disposition" value="filename=load_status.xls">
<cfoutput>
<table cols=2 border=1>
<cfloop from="1" to ="#ArrayLen(anArray)#" index="row">
<tr>
<td>#anArray[row][1]#</td>
<td>#anArray[row][2]#</td>
</tr>
</cfloop>
</table>
</cfoutput>
Try this instead:
<!--- Set content type. --->
<cfset anArray=[]/>
<cfif isDefined(session.stufailedarray)>
<cfset anArray=session.stufailedarray/>
</cfif>
<cfcontent type="Application/vnd.ms-excel">
<cfheader name="Content-Disposition" value="filename=load_status.xls">
<cfoutput>
<table cols=2 border=1>
<cfloop from="1" to ="#ArrayLen(anArray)#" index="row">
<tr>
<td>#anArray[row][1]#</td>
<td>#anArray[row][2]#</td>
</tr>
</cfloop>
</table>
</cfoutput>
Make sure that you configured and enabled application session properly.
To use session variables, enable them in two places:
ColdFusion Administrator The Application.cfc initialization code
This.sessionManagement variable or the active cfapplication tag.
ColdFusion Administrator, Application.cfc, and the cfapplication tag
also provide facilities for configuring session variable behavior,
including the variable time-out.
Configuring and using session variables
According to your question, you have a variable called session.stufailedarray. However in the code that you posted (which generates the error), you have session.stufailarray. This is also the error message that you are getting.
"Element stufailarray is undefined is session"
Note that the set (available) variable, the failed is passed tense, which the error variable is in present tense.
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.
I am using CF-8,windows-XP and IE 5.5.
I am using simple tag namely . but the output i am getting is pure gibberih along witht the text of the file(word document)
upld.cfm
<cffile action="read" file="C:\ColdFusion8\wwwroot\Proj\updl\fileDisk\SOL.doc" variable="fileDisk" >
<cfoutput>#fileDisk#
</cfoutput>
<cfoutput>
<form name="upload" method="post" action="actionUpld.cfm?form_Num=#form_Num#" enctype="multipart/form-data">
<input name="uplForm" id="uplForm" type="file" >
<input type="submit" name="submitUpld" value="Save" onclick="" >
</form>
</cfoutput>
actionUpld.cfm
<cftry>
<cfscript>
newUPL = CreateCFC('cfcs.projDB');
newUPL.Implementation_Num = url.form_Num;
newUPL.uplForm = form.uplForm;
newUPL.putUPL();
</cfscript>
<cfcatch type="any" >
<cfoutput >
<hr>
<h4>Other Error: #cfcatch.Type#</h4>
<li><b>Message:</b> #cfcatch.Message#
<li><b>Detail:</b> #cfcatch.Detail#
<li><b>Error Code:</b> #cfcatch.ErrorCode#
</cfoutput>
</cfcatch>
</cftry>
<cflocation url="upld.cfm??form_Num=#form_Num#" >
How best to use the cffile to output the file ?
Also when i look at the DB, i am getting the file name as
"C:\ColdFusion8\runtime\servers\coldfusion\SERVER-INF\temp\wwwroot-tmp\qeq344.tmp"
How to correct it?
Is there any better way.
Also when i look at the DB, i am
getting the file name as C:\ColdFusion8\runtime\servers\coldfusion\SERVER-INF\temp\wwwroot-tmp\qeq344.tmp
That is a temporary file name assigned to newly uploaded files. On your action page, you need to use cffile action="upload" ... to move that temporary file to the desired location. That will populate a structure called CFFILE with details about the uploaded file, such as CFFILE.serverFile and CFFILE.serverDirectory. (Or use the "result" attribute to output the details to whatever structure name you choose.)
How best to use the cffile to output
the file ?
You cannot display binary files (like *.doc) with cfoutput. To display/download such files in a browser use cfcontent