1

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.

SOS
  • 6,430
  • 2
  • 11
  • 29
help
  • 809
  • 5
  • 18
  • 35
  • It is telling you there is no key named "UploadAllErrors" in that structure. See the linked docs under "errors" for a listing of the key names the errorResult variable will contain. – SOS May 03 '19 at 19:03
  • if I do just #errorResult#, I get Variable ERRORRESULT is undefined. – help May 03 '19 at 19:08
  • same thing if i do #errorResult.CLIENTFILE# or #errorResult[0].CLIENTFILE#, I get Variable ERRORRESULT is undefined. Am I missing something here? – help May 03 '19 at 19:10
  • The `cffile` tag only populates the `errors` attribute variable, when the error occurs while the upload is processed. If any unrelated error/exception occurs, you still end up in the catch and attempt to access the variable. Your error handling is too broad, don't catch all/`any`. – Alex May 03 '19 at 20:20
  • Why does it matter if a file already exists? Why not just use `nameConflict=makeunique`? – SOS May 04 '19 at 02:41

2 Answers2

1

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: Screenshot of Action UploadAll 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:

Screenshot of Action Upload 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

SOS
  • 6,430
  • 2
  • 11
  • 29
  • Fun fact: According to the [docs for action="upload"](https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-tags/tags-f/cffile-action-upload.html), `uploadAllErrors` is also available there. – Alex May 04 '19 at 12:48
  • 1
    @Alex - An error in the documentation? I am shocked I tell you, shocked! ;-) Seriously though, I'm pretty sure it's wrong and they just copied the settings/text from the uploadAll description. In CF2016, the `continueOnError` setting doesn't actually work with "upload". Failures still throw an error and the details are added to the `cfcatch` structure. Plus the description says "when uploading a file fails, the *remaining* files will not be uploaded. ". That doesn't even make sense with a single upload. There are no "remaining" files ;-) So ... I think it's just a documentation bug. – SOS May 04 '19 at 15:50
0

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)">&nbsp;

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>
help
  • 809
  • 5
  • 18
  • 35
  • It's a bug, but no need for javascript hacks. Just use action=uploadAll instead. – SOS May 04 '19 at 23:08