Fixed [JACKSON-377], ThrowableDeserializer not correctly handling @JsonCreator or @JsonAnySetter

diff --git a/release-notes/CREDITS b/release-notes/CREDITS
index 4ae05ab..592e477 100644
--- a/release-notes/CREDITS
+++ b/release-notes/CREDITS
@@ -400,6 +400,9 @@
    * Suggested [JACKSON-308] Configurable date formatting support for XMLGregorianCalendar,
     XMLGregorianCalendar now uses same Date/Calendar serialization as other date types.
    [1.6.0]
-  
-  
+
+Kirill Stokoz:
+  * Reported [JACKSON-377] ThrowableDeserializer was not properly using information from
+    @JsonCreator or @JsonAnySetter
+   [1.6.1]
   
\ No newline at end of file
diff --git a/release-notes/VERSION b/release-notes/VERSION
index d263ff1..fa0bd76 100644
--- a/release-notes/VERSION
+++ b/release-notes/VERSION
@@ -10,7 +10,10 @@
 
    * [JACKSON-372] handle missing primitive type values for @JsonCreator gracefully (with defaults)
    * [JACKSON-376] writing binary data as object field value with Smile failed
-     (report by Shay B)
+     (reported by Shay B)
+   * [JACKSON-377] ThrowableDeserializer was not properly using information from
+      @JsonCreator or @JsonAnySetter
+     (reported by Kirill S)
    * all fixes from 1.5.x up to 1.5.7
 
 ------------------------------------------------------------------------
diff --git a/src/mapper/java/org/codehaus/jackson/map/deser/ThrowableDeserializer.java b/src/mapper/java/org/codehaus/jackson/map/deser/ThrowableDeserializer.java
index e27d0ca..507866e 100644
--- a/src/mapper/java/org/codehaus/jackson/map/deser/ThrowableDeserializer.java
+++ b/src/mapper/java/org/codehaus/jackson/map/deser/ThrowableDeserializer.java
@@ -13,12 +13,12 @@
 public class ThrowableDeserializer
     extends BeanDeserializer
 {
-    final static String PROP_NAME_MESSAGE = "message";
+    protected final static String PROP_NAME_MESSAGE = "message";
 
     /*
-    ///////////////////////////////////////////////////////
-    // Construction
-    ///////////////////////////////////////////////////////
+    /**********************************************************
+    /* Construction
+    /**********************************************************
      */
 
     public ThrowableDeserializer(JavaType type)
@@ -27,15 +27,32 @@
     }
 
     /*
-    ///////////////////////////////////////////////////////
-    // Overridden methods
-    ///////////////////////////////////////////////////////
+    /**********************************************************
+    /* Overridden methods
+    /**********************************************************
      */
 
     @Override
     public Object deserializeFromObject(JsonParser jp, DeserializationContext ctxt)
         throws IOException, JsonProcessingException
     {
+        // 30-Sep-2010, tatu: Need to allow use of @JsonCreator, so:
+        if (_propertyBasedCreator != null) { // proper @JsonCreator
+            return _deserializeUsingPropertyBased(jp, ctxt);
+        }
+        if (_delegatingCreator != null) { // delegate based one (single-arg, no property name)
+            return _delegatingCreator.deserialize(jp, ctxt);
+        }
+        if (_beanType.isAbstract()) { // for good measure, check this too
+            throw JsonMappingException.from(jp, "Can not instantiate abstract type "+_beanType
+                    +" (need to add/enable type information?)");
+        }
+        // and finally, verify we do have single-String arg constructor (if no @JsonCreator)
+        if (_stringCreator == null) {
+            throw new JsonMappingException("Can not deserialize Throwable of type "+_beanType
+                    +" without having either single-String-arg constructor; or explicit @JsonCreator");
+        }
+        
         Object throwable = null;
         Object[] pending = null;
         int pendingIx = 0;
@@ -73,6 +90,17 @@
                 }
                 continue;
             }
+            /* As per [JACKSON-313], things marked as ignorable should not be
+             * passed to any setter
+             */
+            if (_ignorableProps != null && _ignorableProps.contains(propName)) {
+                jp.skipChildren();
+                continue;
+            }
+            if (_anySetter != null) {
+                _anySetter.deserializeAndSet(jp, ctxt, throwable, propName);
+                continue;
+            }
             // Unknown: let's call handler method
             handleUnknownProperty(jp, ctxt, throwable, propName);
         }
diff --git a/src/test/org/codehaus/jackson/map/deser/TestExceptionDeserialization.java b/src/test/org/codehaus/jackson/map/deser/TestExceptionDeserialization.java
index 4b69433..527c4a2 100644
--- a/src/test/org/codehaus/jackson/map/deser/TestExceptionDeserialization.java
+++ b/src/test/org/codehaus/jackson/map/deser/TestExceptionDeserialization.java
@@ -3,7 +3,11 @@
 import org.codehaus.jackson.map.BaseMapTest;
 
 import java.io.IOException;
+import java.util.*;
 
+import org.codehaus.jackson.annotate.JsonAnySetter;
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonProperty;
 import org.codehaus.jackson.map.*;
 
 /**
@@ -12,8 +16,39 @@
 public class TestExceptionDeserialization
     extends BaseMapTest
 {
-    public void testIOException()
-        throws IOException
+    @SuppressWarnings("serial")
+    static class MyException extends Exception
+    {
+        protected int value;
+
+        protected String myMessage;
+        protected HashMap<String,Object> stuff = new HashMap<String, Object>();
+        
+        @JsonCreator
+        MyException(@JsonProperty("message") String msg, @JsonProperty("value") int v)
+        {
+            super(msg);
+            myMessage = msg;
+            value = v;
+        }
+
+        public int getValue() { return value; }
+        
+        public String getFoo() { return "bar"; }
+
+        @JsonAnySetter public void setter(String key, Object value)
+        {
+            stuff.put(key, value);
+        }
+    }
+    
+    /*
+    /**********************************************************
+    /* Tests
+    /**********************************************************
+     */
+
+    public void testIOException() throws IOException
     {
         ObjectMapper mapper = new ObjectMapper();
         IOException ioe = new IOException("TEST");
@@ -24,4 +59,18 @@
 
         assertEquals(ioe.getMessage(), result.getMessage());
     }
+
+    // As per [JACKSON-377]
+    public void testWithCreator() throws IOException
+    {
+        final String MSG = "the message";
+        ObjectMapper mapper = new ObjectMapper();
+        String json = mapper.writeValueAsString(new MyException(MSG, 3));
+
+        MyException result = mapper.readValue(json, MyException.class);
+        assertEquals(MSG, result.getMessage());
+        assertEquals(3, result.value);
+        assertEquals(1, result.stuff.size());
+        assertEquals(result.getFoo(), result.stuff.get("foo"));
+    }
 }