13

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?

  • 2
    I'm by no means an authority on this but it seems to be a common thing for aspects of the CRM which are outside of the 'core' system as it were. Chances are there's a dedicated machine dealing with file uploads and the like and this is handled outside of the normal Apex environment; if that is indeed the case it could explain why you don't get the exceptions raised in your process. Also, excellent question well asked. – Matt Lacey Jan 29 '14 at 2:52
  • I'm able to reproduce this and then when googled it found this post, so you are not alone :) Serioulsy internal catch impacts as that error is generated and rest of code still executes, which leaves functionality instable state as one fails and email is sent with partial attachments. – Chirag Mehta Apr 28 '16 at 18:19
7
+50

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.

  • This does not work on IE8 for those of us stuck in companies with old standards. – Daniel Hoechst Jan 29 '14 at 16:39
  • 1
    Yes, for old browsers you could adapt the script using ActiveXObject("Scripting.FileSystemObject") to get the size – Martin Borthiry Jan 29 '14 at 17:16
  • Yes. Cross-browser support restricts me as well to validate file size via Javascript. – VarunC Jan 30 '14 at 6:20
  • It was really easy to make the script cross-browser. I updated the answer – Martin Borthiry Jan 30 '14 at 7:57
0

No, this is the way I have done it as well for custom file uploads. They set the limits on the CRM for a reason. I do wish some things were handled in a better way for developers but I think this solution for an apex page still holds true.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.