[SalesForce] Large size Attachment upload auto-removed by Salesforce. Is it a bug

I've a Visualforce page that uploads multiple Attachments selected by user. I used following code to upload attachments:

...
<apex:repeat value="{!AttList}" var="att">
    <apex:inputFile value="{!att.Body}" filesize="{!att.BodyLength}" />
</apex:repeat>
...

Apex code:

public class AttachmentController {
    ...
    public list<Attachment> AttList { get;set; }
    public void UploadAtt() {
        try {
            for (Attachment a : AttList) {
                if (a.BodyLegnth > 5242880)
                     throw new CustomException('File size is larger than 5 MB');
            }
        }
        catch(Exception ex) {
            ApexPages.addMessages( ex );
        }
    }
    ...
}

But the Exception never gets thrown because salesforce automatically removes the file from the AttList variable, totally annoying behavior. This has been noticed for files larger than 5 MB.

Now, I tried something different and bind the inputFIle component to a wrapper class like this:

...
<apex:repeat value="{!AttList}" var="wrap">
    <apex:inputFile value="{!wrap.att.Body}" filesize="{!wrap.att.BodyLength}" />
</apex:repeat>
...

Apex code:

public class AttachmentController {
    ...
    public list<Attachment> AttList { get;set; }
    public void UploadAtt() {
        try {
            for (wAtt a : AttList) {
                Attachment a = w.att;
                if (a.BodyLegnth > 5242880)
                    throw new CustomException('File size is larger than 5 MB');
            }
        }
        catch(Exception ex) {
            ApexPages.addMessages( ex );
        }
    }
    ...
    class wAtt {
        public Attachment att { get;set; }
    }
}

Strangely this FIXES the bug to certain bit. So, now I can upload a file over 5 MB and now the error is trapped. And the Exception is thrown to user notifying that error has occurred while uploading the attachments.

This is a very strange issue. "Usually" one would expect if there is a limitation on platform, developer needs to trap it and handle it, but this time salesforce has taken that away from us and made it automatic. But this has raised a serious limitation such that how will user be notified why attachment has not been uploaded. It doesn't make sense to me if user has selected 5 attachments, and when I do insert the list, only 4 gets inserted but 1 failed "without" ever notifying the end user.

Now, even with this fix, it allows uploading of Attachment list with file over 5 MB and below 10 MB, and automatically ignore/remove any file that is larger than 10 MB by salesforce without getting trapped in Apex class code. It really is very bad.

Does anyone else have face this issue or have any permanent fix for this?

Best Answer

I really don't know how catch the uploaded file error using apex (server-side), but I've avoided that limitation using javascript (client-side) before the form is submitted in order to notify the user about the limitation.

This is an example:

    <apex:page standardController="document" >

        <apex:form styleClass="js-wrapp">
            <apex:inputFile value="{!document.body}" filename="{!document.name}"/ >
            <apex:commandButton value="Save" action="{!save}"/>
        </apex:form>


       <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"  />
       <script>

function getIEFileSize(file){
     var myFSO = new ActiveXObject("Scripting.FileSystemObject"),
    filepath = file.value,
    thefile = myFSO.getFile(filepath);
    return thefile.size;
}

   $(function(){
    $('form.js-wrapper').submit(function(){
        var isOk = true;
        $('input[type=file]').each(function(){
            if(typeof this.files[0] !== 'undefined'){
                var file = this.files[0],
                size = typeof ActiveXObject !== 'undefined' ?
                    getIEFileSize(file)
                    :
                    file.fileSize || file.size;

                isOk = 5242880 > size;
                if(!isOk){
                  alert(this.files[0].name +' file is bigger than 5MB');
                }

                return isOk;
            }
        });
        return isOk;
    });
   });

       </script>

</apex:page>

The script will work for any amount of file inputs checking all of them.