ColdFusion: как получить имя файла неудачной загрузки

Я пытаюсь поместить имя файла неудачной загрузки в электронное письмо внутри попытки/пойма, но мне не повезло.

На основании этой документации — FileUploadAll() - я решил, что буду использовать ошибку.

<cftry>
    <cffile destination="#FULLPATH#" action="upload" nameconflict="ERROR" continueOnError="true" filefield="FileName" />
    <cfcatch type="Any" >
        <cf_EmailHandler from="[email protected]" to="[email protected]" 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>

Я получаю следующую ошибку:

Элемент UPLOADALLERRORS не определен в CFFILE

Итак, я пытаюсь исправить это:

<cftry>
    <cffile destination="#FULLPATH#" action="upload" nameconflict="ERROR" Errors="errorResult" continueOnError="true" filefield="FileName" />
    <cfcatch type="Any" >
        <cf_EmailHandler from="[email protected]" to="[email protected]" 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>

Затем я получаю:

Элемент UPLOADALLERRORS не определен в ERRORRESULT.

Любая идея о том, что я делаю неправильно, или другой способ отобразить имя неудачной загрузки? Также я использую ColdFusion 11.


person help    schedule 03.05.2019    source источник
comment
Он сообщает вам, что в этой структуре нет ключа с именем UploadAllErrors. См. связанные документы в разделе ошибок для списка имен ключей, которые будет содержать переменная errorResult.   -  person SOS    schedule 03.05.2019
comment
если я делаю просто #errorResult#, я получаю, что переменная ERRORRESULT не определена.   -  person help    schedule 03.05.2019
comment
то же самое, если я делаю #errorResult.CLIENTFILE# или #errorResult[0].CLIENTFILE#, я получаю, что переменная ERRORRESULT не определена. Я что-то упустил здесь?   -  person help    schedule 03.05.2019
comment
Тег cffile заполняет переменную атрибута errors только тогда, когда во время загрузки возникает ошибка. Если возникает какая-либо несвязанная ошибка/исключение, вы все равно попадаете в ловушку и пытаетесь получить доступ к переменной. Ваша обработка ошибок слишком широка, не перехватывайте все/any.   -  person Alex    schedule 03.05.2019
comment
Какая разница, если файл уже существует? Почему бы просто не использовать nameConflict=makeunique?   -  person SOS    schedule 04.05.2019


Ответы (2)


Обновление:

В отчете об ошибке CF-4204290 эта проблема в настоящее время указана как "Исправить".

TL;DR;

Это ошибка документации. Атрибут continueOnError не поддерживается с действие=загрузить. Используйте action=uploadAll вместо этого. Имейте в виду, что "uploadAll" поддерживает несколько файлов, поэтому результаты будут возвращены в виде массива структур.


Причина, по которой это не работает, заключается в том, что код использует неправильное «действие». Это должно быть action="uploadAll". Поскольку вы используете continueOnError="true", CF заполняет структуру любыми возникающими ошибками. По умолчанию используется CFFILE, но вы можете указать другое имя переменной, используя атрибут errors.

<cffile destination="c:/some/path/" 
    action="uploadAll" 
    nameconflict="ERROR" 
    continueOnError="true" 
    filefield="file_path" />

Обновление:

Как указано в комментариях, документация делает saycontinueOnError является поддерживаемым атрибутом для action=upload. Однако, ИМО, это ошибка документации. Adobe, вероятно, просто скопировала текст из описания action=uploadAll.

Интересно, что документация для FileUpload() вообще не перечисляет этот атрибут. Отчет об ошибке CF-4199503 подтверждает, что версия функции не поддерживает ее. Основываясь на моих тестах ниже с CF11 и CF2016, я пришел к выводу, что он не поддерживается ни в одной из версий.


Тестовое действие=Загрузить все

Загрузка файла, который уже существует в целевом каталоге, не вызывает серьезной ошибки. CF заполняет указанную переменную деталями ошибки и выводит их на экран:

<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>

Результаты: Скриншот действия Загрузить все результаты

Тестовое действие=Загрузить

Измените действие на action="upload", и код не сработает. ColdFusion НЕ:

  • Продолжить обработку после ошибки .. или
  • Заполните cffile информацией об ошибке... или
  • Создайте результирующую переменную с именем атрибута errors

Результаты:

Скриншот результатов загрузки действий

Обратите внимание: исключение необязательного атрибута errors приводит к тем же результатам. Он работает должным образом при использовании action=uploadAll и завершается с ошибкой при использовании action=upload

person SOS    schedule 04.05.2019
comment
Интересный факт: согласно docs для action=upload, uploadAllErrors также доступен там. - person Alex; 04.05.2019
comment
@Alex - ошибка в документации? Я в шоке, скажу я вам, в шоке! ;-) А если серьезно, я почти уверен, что это неправильно, и они просто скопировали настройки/текст из описания uploadAll. В CF2016 параметр continueOnError фактически не работает с загрузкой. Сбои по-прежнему выдают ошибку, а подробности добавляются в структуру cfcatch. Кроме того, в описании говорится, что при сбое загрузки файла оставшиеся файлы не будут загружены. . Это даже не имеет смысла с одной загрузкой. Оставшихся файлов нет ;-) Так что... Думаю, это просто ошибка документации. - person SOS; 04.05.2019

На странице формы я зафиксировал имя файла с помощью 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;
  } 
}

На следующей странице я просто показываю переданное имя фильма.

<cftry>
    <cffile destination="#FULLPATH#" action="upload" nameconflict="ERROR" Errors="errorResult" continueOnError="true" filefield="FileName" />
    <cfcatch type="Any" >
        <cf_EmailHandler from="[email protected]" to="[email protected]" 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>
person help    schedule 03.05.2019
comment
Это ошибка, но нет необходимости в хаках javascript. Вместо этого просто используйте action=uploadAll. - person SOS; 05.05.2019