5

I am facing the issue on the case comment size. There is an inbound email handler which creates a case comment on a specific case record based on the incoming email body.

Sometimes its giving error - "STRING_TOO_LONG, Body: data value too large". Then i checked the limit for case comment body and its 4000 bytes and not characters.

Now the problem is how do i check for size of a string as bytes and not as characters in apex? I found that string .size() method returns number of characters and not no of bytes.

Please help.

Thanks

3 Answers 3

9

The documentation for String.length() (there is no String.size()) explains that it:

Returns the number of 16-bit Unicode characters contained in the String.

So the number of 8 bit bytes is 2x the length of the string. (And so to fix the problem you need to truncate at 2000 characters.)

PS Looks like Blob.valueOf(stringValue).size() is a better way to go - see that answer.

2
  • Actually, your conversion doesn't work. Truncating to 2000 characters is safe, but you are probably chopping off a lot more than you need. For example, I have a string from an email body which is 3999 characters. If I convert it to a blob and the check the size, it is 4015. This won't fit. If I shorten it a bit more so the blob size is less than 4000, it fits. Commented Sep 24, 2014 at 21:23
  • @DanielHoechst I guess the question here is the encoding: UTF-8 with mostly single byte characters will occupy not many more bytes that the size in characters whereas UTF-16 (Unicode) will occupy x2. It appears to be possible to assign a String directly to CaseComment.CommentBody - is Blob relevant here? Or is using Blob a way to get the number of bytes in UTF-8 format?
    – Keith C
    Commented Sep 24, 2014 at 21:42
5

Use Blob.valueOf(stringValue).size() to get the size in bytes. It all depends on what characters are sent in the email that determines the size in bytes.

The following method worked for me to abbreviate the string in bytes:

private String byteAbbreviate(String stringToAbbreviate, Integer byteLength) {
    //First abbrevate using the character length. This will get us close
    stringToAbbreviate = stringToAbbreviate.abbreviate(byteLength);
    Integer abbLength = byteLength;
    while (Blob.valueOf(stringToAbbreviate).size() > byteLength) {
      abbLength = abbLength - 1;
      stringToAbbreviate = stringToAbbreviate.abbreviate(abbLength);
    }
    return stringToAbbreviate;
}

You can use DMLOptions to truncate the CaseComment when it is inserted.

Database.DMLOptions dmo = new Database.DMLOptions();
dmo.allowFieldTruncation = true;
Database.insert(comment, dmo);
4
  • Is the Blob Class documentation for size wrong when it says "Returns the number of characters in the Blob" rather than the number of bytes?
    – Keith C
    Commented Sep 24, 2014 at 21:44
  • I think so. My testing seems to be if the Blob size of the string is less than 4k, it will go into CaseComments. If it is greater, it won't fit. Commented Sep 24, 2014 at 22:17
  • Simple enough then. +1 from me.
    – Keith C
    Commented Sep 25, 2014 at 7:32
  • Daniel - you saved my bacon on this Friday night after deploying and end user discovering issues with CaseComments in Croat.
    – cropredy
    Commented May 14, 2022 at 3:10
0
Database.DMLOptions dmo = new Database.DMLOptions();
dmo.allowFieldTruncation = true;
Database.insert(comment, dmo);

If I understand correctly, this will truncate the casecomment body only when the characters exceed 4000 right?

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .