I'm using Jackson to deserialize an Exception object from JSON. Here's a simplified demo (using an implicit delegating creator):
throw new ObjectMapper().readValue("\"custom error message\"", Exception.class);
This works, but unfortunately the stack trace includes the Jackson frames leading up to the instantiation of the exception:
Exception in thread "main" java.lang.Exception: custom error message
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.fasterxml.jackson.databind.introspect.AnnotatedConstructor.call1(AnnotatedConstructor.java:133)
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:332)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer._deserializeFromString(StdDeserializer.java:265)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1495)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:197)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:187)
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4674)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3629)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3597)
Is there a way to clean it up so it looks like it was created on the same line it was thrown?
You can use fillInStackTrace()
to reset the stack trace to the point at which you throw:
public class Main {
public static void main(String[] args) throws Exception {
Exception e = createException();
e.fillInStackTrace();
throw e;
}
private static Exception createException() {
return new Exception("my message");
}
}
produces:
Exception in thread "main" java.lang.Exception: my message
at org.example.Main.main(Main.java:11)
without the call to `fillInStackTrace() the output is:
Exception in thread "main" java.lang.Exception: my message
at org.example.Main.createException(Main.java:16)
at org.example.Main.main(Main.java:10)