Skip to content

Commit 12351a9

Browse files
author
Loïc Lambert
committed
May put any kind of extra field value
- adds a method in ServiceException to put an extra field value that may be unsafe (array, List, Map, ...) - adds a unit test
1 parent e73728e commit 12351a9

2 files changed

Lines changed: 95 additions & 0 deletions

File tree

endpoints-framework/src/main/java/com/google/api/server/spi/ServiceException.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,21 @@ public ServiceException putExtraField(String fieldName, Number value) {
153153
return putExtraFieldInternal(fieldName, value);
154154
}
155155

156+
/**
157+
* Associates to this exception an extra field as a field name/value pair. If a field
158+
* with the same name was previously set, the old value is replaced by the specified
159+
* value.<br>
160+
* This unsafe version accepts any POJO as is: nor defensive copy nor conversion are made.
161+
* So {@code value} should not be modified or reused after the call of this method.
162+
* @return this
163+
* @throws NullPointerException if {@code fieldName} is {@code null}.
164+
* @throws IllegalArgumentException if {@code fieldName} is one of the reserved field
165+
* names {@link #EXTRA_FIELDS_RESERVED_NAMES}.
166+
*/
167+
protected ServiceException putExtraFieldUnsafe(String fieldName, Object value) {
168+
return putExtraFieldInternal(fieldName, value);
169+
}
170+
156171
private ServiceException putExtraFieldInternal(String fieldName, Object value) {
157172
Preconditions.checkNotNull(fieldName);
158173
Preconditions.checkArgument(!EXTRA_FIELDS_RESERVED_NAMES.contains(fieldName), "The field name '%s' is reserved", fieldName);

endpoints-framework/src/test/java/com/google/api/server/spi/response/RestResponseResultWriterTest.java

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@
3232
import org.skyscreamer.jsonassert.JSONAssert;
3333
import org.springframework.mock.web.MockHttpServletResponse;
3434

35+
import java.util.Arrays;
36+
import java.util.HashMap;
37+
import java.util.List;
38+
import java.util.Map;
39+
3540
/**
3641
* Tests for {@link RestResponseResultWriter}.
3742
*/
@@ -269,4 +274,79 @@ public void writeError_extraFields() throws Exception {
269274
writer.writeError(serviceException);
270275
JSONAssert.assertEquals(expectedError, response.getContentAsString(), true);
271276
}
277+
278+
@Test
279+
public void writeError_extraFieldsUnsafe() throws Exception {
280+
281+
MockHttpServletResponse response = new MockHttpServletResponse();
282+
RestResponseResultWriter writer = new RestResponseResultWriter(response, null, true /* prettyPrint */,
283+
true /* addContentLength */, true /* enableExceptionCompatibility */);
284+
285+
TestServiceExceptionExtraFieldUnsafe serviceException = new TestServiceExceptionExtraFieldUnsafe(400, "customMessage", "customReason", "customDomain");
286+
287+
// Extra field array
288+
Boolean[] booleans = new Boolean[] { TRUE, FALSE, TRUE };
289+
290+
// Extra field List
291+
List<String> stringList = Arrays.asList("First", "Second", "Last");
292+
293+
// Extra field Map
294+
Map<Integer, TestValue> map = new HashMap<>();
295+
map.put(1, new TestValue("Alice", 7, TestEnum.VALUE1));
296+
map.put(2, new TestValue("Bob", 12, TestEnum.VALUE2));
297+
map.put(3, new TestValue("Clark", 31, TestEnum.VALUE3));
298+
299+
serviceException.putExtraFieldUnsafe("someExtraNull", null)
300+
.putExtraFieldUnsafe("someExtraArray", booleans)
301+
.putExtraFieldUnsafe("someExtraList", stringList)
302+
.putExtraFieldUnsafe("someExtraMap", map);
303+
304+
String expectedError = "{\"error\": {\"errors\": [{" +
305+
" \"domain\": \"customDomain\"," +
306+
" \"reason\": \"customReason\"," +
307+
" \"message\": \"customMessage\"," +
308+
" \"someExtraNull\": null," +
309+
" \"someExtraArray\": [true, false, true]," +
310+
" \"someExtraList\": [\"First\", \"Second\", \"Last\"]," +
311+
" \"someExtraMap\": {" +
312+
" \"1\": {\"name\": \"Alice\", \"age\": 7, \"testEnum\": \"VALUE1\"}," +
313+
" \"2\": {\"name\": \"Bob\", \"age\": 12, \"testEnum\": \"VALUE2\"}," +
314+
" \"3\": {\"name\": \"Clark\", \"age\": 31, \"testEnum\": \"VALUE3\"}" +
315+
" }" +
316+
" }]," +
317+
" \"code\": 400," +
318+
" \"message\": \"customMessage\"" +
319+
"}}";
320+
321+
writer.writeError(serviceException);
322+
JSONAssert.assertEquals(expectedError, response.getContentAsString(), true);
323+
}
324+
325+
enum TestEnum {
326+
VALUE1, VALUE2, VALUE3;
327+
}
328+
329+
class TestValue {
330+
public String name;
331+
public int age;
332+
public TestEnum testEnum;
333+
334+
TestValue(String name, int age, TestEnum testEnum) {
335+
this.name = name;
336+
this.age = age;
337+
this.testEnum = testEnum;
338+
}
339+
}
340+
341+
class TestServiceExceptionExtraFieldUnsafe extends ServiceException {
342+
343+
TestServiceExceptionExtraFieldUnsafe(int statusCode, String statusMessage, String reason, String domain) {
344+
super(statusCode, statusMessage, reason, domain);
345+
}
346+
347+
@Override
348+
public TestServiceExceptionExtraFieldUnsafe putExtraFieldUnsafe(String fieldName, Object value) {
349+
return (TestServiceExceptionExtraFieldUnsafe) super.putExtraFieldUnsafe(fieldName, value);
350+
}
351+
}
272352
}

0 commit comments

Comments
 (0)