Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/changelog/122427.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 122427
summary: Improve size limiting string message
area: Infra/Core
type: enhancement
issues: []
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ public void testResultSizeLimit() throws IOException {
ex.getCause().getCause(),
allOf(
instanceOf(SizeLimitingStringWriter.SizeLimitExceededException.class),
transformedMatch(Throwable::getMessage, endsWith("has exceeded the size limit [1024]"))
transformedMatch(Throwable::getMessage, endsWith("has size [1030] which exceeds the size limit [1024]"))
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,39 +30,59 @@ public SizeLimitingStringWriter(int sizeLimit) {
this.sizeLimit = sizeLimit;
}

private void checkSizeLimit(int additionalChars) {
int bufLen = getBuffer().length();
if (bufLen + additionalChars > sizeLimit) {
throw new SizeLimitExceededException(
Strings.format("String [%s...] has exceeded the size limit [%s]", getBuffer().substring(0, Math.min(bufLen, 20)), sizeLimit)
);
private int limitSize(int additionalChars) {
int neededSize = getBuffer().length() + additionalChars;
if (neededSize > sizeLimit) {
return additionalChars - (neededSize - sizeLimit);
}
return additionalChars;
}

private void throwSizeLimitExceeded(int limitedChars, int requestedChars) {
assert limitedChars < requestedChars;
int bufLen = getBuffer().length();
int foundSize = bufLen - limitedChars + requestedChars; // reconstitute original
String selection = getBuffer().substring(0, Math.min(bufLen, 20));
throw new SizeLimitExceededException(
Strings.format("String [%s...] has size [%d] which exceeds the size limit [%d]", selection, foundSize, sizeLimit)
);
}

@Override
public void write(int c) {
checkSizeLimit(1);
if (limitSize(1) != 1) {
throwSizeLimitExceeded(0, 1);
}
super.write(c);
}

// write(char[]) delegates to write(char[], int, int)

@Override
public void write(char[] cbuf, int off, int len) {
checkSizeLimit(len);
super.write(cbuf, off, len);
int limitedLen = limitSize(len);
if (limitedLen > 0) {
super.write(cbuf, off, limitedLen);
}
if (limitedLen != len) {
throwSizeLimitExceeded(limitedLen, len);
}
}

@Override
public void write(String str) {
checkSizeLimit(str.length());
super.write(str);
this.write(str, 0, str.length());
}

@Override
public void write(String str, int off, int len) {
checkSizeLimit(len);
super.write(str, off, len);
int limitedLen = limitSize(len);
if (limitedLen > 0) {
super.write(str, off, limitedLen);
}
if (limitedLen != len) {
throwSizeLimitExceeded(limitedLen, len);
}
}

// append(...) delegates to write(...) methods
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

import org.elasticsearch.test.ESTestCase;

import static org.hamcrest.Matchers.equalTo;

public class SizeLimitingStringWriterTests extends ESTestCase {
public void testSizeIsLimited() {
SizeLimitingStringWriter writer = new SizeLimitingStringWriter(10);
Expand All @@ -26,4 +28,11 @@ public void testSizeIsLimited() {
expectThrows(SizeLimitingStringWriter.SizeLimitExceededException.class, () -> writer.append("a"));
expectThrows(SizeLimitingStringWriter.SizeLimitExceededException.class, () -> writer.append("a", 0, 1));
}

public void testLimitMessage() {
SizeLimitingStringWriter writer = new SizeLimitingStringWriter(3);

var e = expectThrows(SizeLimitingStringWriter.SizeLimitExceededException.class, () -> writer.write("abcdefgh"));
assertThat(e.getMessage(), equalTo("String [abc...] has size [8] which exceeds the size limit [3]"));
}
}