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