Tatu Saloranta | ab4f17f | 2016-10-06 19:27:32 -0700 | [diff] [blame] | 1 | package com.fasterxml.jackson.databind.deser.exc; |
Tatu Saloranta | a63c203 | 2011-12-24 00:26:53 -0800 | [diff] [blame] | 2 | |
Tatu Saloranta | 9b7ffec | 2016-05-03 22:13:13 -0700 | [diff] [blame] | 3 | import java.io.IOException; |
Tatu Saloranta | a63c203 | 2011-12-24 00:26:53 -0800 | [diff] [blame] | 4 | import java.util.*; |
| 5 | |
Tatu Saloranta | 7a69571 | 2016-05-03 21:52:42 -0700 | [diff] [blame] | 6 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
Tatu Saloranta | a63c203 | 2011-12-24 00:26:53 -0800 | [diff] [blame] | 7 | import com.fasterxml.jackson.databind.*; |
| 8 | |
| 9 | /** |
| 10 | * Unit tests for verifying that simple exceptions can be serialized. |
| 11 | */ |
| 12 | public class TestExceptionSerialization |
| 13 | extends BaseMapTest |
| 14 | { |
Tatu Saloranta | 7a69571 | 2016-05-03 21:52:42 -0700 | [diff] [blame] | 15 | @SuppressWarnings("serial") |
| 16 | @JsonIgnoreProperties({ "bogus1" }) |
| 17 | static class ExceptionWithIgnoral extends RuntimeException |
| 18 | { |
| 19 | public int bogus1 = 3; |
| 20 | |
| 21 | public int bogus2 = 5; |
| 22 | |
Tatu Saloranta | 9b7ffec | 2016-05-03 22:13:13 -0700 | [diff] [blame] | 23 | protected ExceptionWithIgnoral() { } |
Tatu Saloranta | 7a69571 | 2016-05-03 21:52:42 -0700 | [diff] [blame] | 24 | public ExceptionWithIgnoral(String msg) { |
| 25 | super(msg); |
| 26 | } |
| 27 | } |
| 28 | |
Tatu Saloranta | ccd7212 | 2016-09-12 22:56:46 -0700 | [diff] [blame] | 29 | // [databind#1368] |
| 30 | static class NoSerdeConstructor { |
| 31 | private String strVal; |
| 32 | public String getVal() { return strVal; } |
| 33 | public NoSerdeConstructor( String strVal ) { |
| 34 | this.strVal = strVal; |
| 35 | } |
| 36 | } |
| 37 | |
Tatu Saloranta | a63c203 | 2011-12-24 00:26:53 -0800 | [diff] [blame] | 38 | /* |
Tatu Saloranta | f3bb342 | 2012-03-20 16:20:01 -0700 | [diff] [blame] | 39 | /********************************************************** |
| 40 | /* Tests |
| 41 | /********************************************************** |
Tatu Saloranta | a63c203 | 2011-12-24 00:26:53 -0800 | [diff] [blame] | 42 | */ |
| 43 | |
Tatu Saloranta | 7a69571 | 2016-05-03 21:52:42 -0700 | [diff] [blame] | 44 | private final ObjectMapper MAPPER = new ObjectMapper(); |
| 45 | |
Tatu Saloranta | a63c203 | 2011-12-24 00:26:53 -0800 | [diff] [blame] | 46 | public void testSimple() throws Exception |
| 47 | { |
Tatu Saloranta | a63c203 | 2011-12-24 00:26:53 -0800 | [diff] [blame] | 48 | String TEST = "test exception"; |
Tatu Saloranta | 7a69571 | 2016-05-03 21:52:42 -0700 | [diff] [blame] | 49 | Map<String,Object> result = writeAndMap(MAPPER, new Exception(TEST)); |
Tatu Saloranta | f3bb342 | 2012-03-20 16:20:01 -0700 | [diff] [blame] | 50 | // JDK 7 has introduced a new property 'suppressed' to Throwable |
| 51 | Object ob = result.get("suppressed"); |
| 52 | if (ob != null) { |
| 53 | assertEquals(5, result.size()); |
| 54 | } else { |
| 55 | assertEquals(4, result.size()); |
| 56 | } |
| 57 | |
Tatu Saloranta | a63c203 | 2011-12-24 00:26:53 -0800 | [diff] [blame] | 58 | assertEquals(TEST, result.get("message")); |
| 59 | assertNull(result.get("cause")); |
| 60 | assertEquals(TEST, result.get("localizedMessage")); |
| 61 | |
| 62 | // hmmh. what should we get for stack traces? |
| 63 | Object traces = result.get("stackTrace"); |
| 64 | if (!(traces instanceof List<?>)) { |
| 65 | fail("Expected a List for exception member 'stackTrace', got: "+traces); |
| 66 | } |
| 67 | } |
Tatu Saloranta | 7a69571 | 2016-05-03 21:52:42 -0700 | [diff] [blame] | 68 | |
| 69 | // for [databind#877] |
Tatu Saloranta | 9b7ffec | 2016-05-03 22:13:13 -0700 | [diff] [blame] | 70 | @SuppressWarnings("unchecked") |
Tatu Saloranta | 7a69571 | 2016-05-03 21:52:42 -0700 | [diff] [blame] | 71 | public void testIgnorals() throws Exception |
| 72 | { |
Tatu Saloranta | 9b7ffec | 2016-05-03 22:13:13 -0700 | [diff] [blame] | 73 | ExceptionWithIgnoral input = new ExceptionWithIgnoral("foobar"); |
| 74 | input.initCause(new IOException("surprise!")); |
| 75 | |
Tatu Saloranta | 7a69571 | 2016-05-03 21:52:42 -0700 | [diff] [blame] | 76 | // First, should ignore anything with class annotations |
| 77 | String json = MAPPER |
Tatu Saloranta | 9b7ffec | 2016-05-03 22:13:13 -0700 | [diff] [blame] | 78 | .writerWithDefaultPrettyPrinter() |
| 79 | .writeValueAsString(input); |
Tatu Saloranta | 7a69571 | 2016-05-03 21:52:42 -0700 | [diff] [blame] | 80 | |
Tatu Saloranta | 7a69571 | 2016-05-03 21:52:42 -0700 | [diff] [blame] | 81 | Map<String,Object> result = MAPPER.readValue(json, Map.class); |
| 82 | assertEquals("foobar", result.get("message")); |
| 83 | |
| 84 | assertNull(result.get("bogus1")); |
| 85 | assertNotNull(result.get("bogus2")); |
| 86 | |
| 87 | // and then also remova second property with config overrides |
| 88 | ObjectMapper mapper = new ObjectMapper(); |
| 89 | mapper.configOverride(ExceptionWithIgnoral.class) |
| 90 | .setIgnorals(JsonIgnoreProperties.Value.forIgnoredProperties("bogus2")); |
Tatu Saloranta | 9b7ffec | 2016-05-03 22:13:13 -0700 | [diff] [blame] | 91 | String json2 = mapper |
| 92 | .writeValueAsString(new ExceptionWithIgnoral("foobar")); |
| 93 | |
| 94 | Map<String,Object> result2 = mapper.readValue(json2, Map.class); |
| 95 | assertNull(result2.get("bogus1")); |
| 96 | assertNull(result2.get("bogus2")); |
| 97 | |
| 98 | // and try to deserialize as well |
| 99 | ExceptionWithIgnoral output = mapper.readValue(json2, ExceptionWithIgnoral.class); |
| 100 | assertNotNull(output); |
| 101 | assertEquals("foobar", output.getMessage()); |
Tatu Saloranta | 7a69571 | 2016-05-03 21:52:42 -0700 | [diff] [blame] | 102 | } |
Tatu Saloranta | ccd7212 | 2016-09-12 22:56:46 -0700 | [diff] [blame] | 103 | |
| 104 | // [databind#1368] |
| 105 | public void testJsonMappingExceptionSerialization() throws IOException { |
| 106 | Exception e = null; |
| 107 | // cant deserialize due to unexpected constructor |
| 108 | try { |
| 109 | MAPPER.readValue( "{ \"val\": \"foo\" }", NoSerdeConstructor.class ); |
| 110 | fail("Should not pass"); |
| 111 | } catch (JsonMappingException e0) { |
| 112 | verifyException(e0, "no suitable constructor"); |
| 113 | e = e0; |
| 114 | } |
| 115 | // but should be able to serialize new exception we got |
| 116 | String json = MAPPER.writeValueAsString(e); |
| 117 | JsonNode root = MAPPER.readTree(json); |
| 118 | String msg = root.path("message").asText(); |
| 119 | String MATCH = "no suitable constructor"; |
| 120 | if (!msg.contains(MATCH)) { |
| 121 | fail("Exception should contain '"+MATCH+"', does not: '"+msg+"'"); |
| 122 | } |
| 123 | } |
Tatu Saloranta | a63c203 | 2011-12-24 00:26:53 -0800 | [diff] [blame] | 124 | } |