Skip to content

Commit

Permalink
Implement FasterXML#3177
Browse files Browse the repository at this point in the history
Supporting the suppressed property when deserializing Throwable
  • Loading branch information
klaasdellschaft committed Jun 18, 2021
1 parent 9b57715 commit d14ebdc
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class ThrowableDeserializer
private static final long serialVersionUID = 1L;

protected final static String PROP_NAME_MESSAGE = "message";
protected final static String PROP_NAME_SUPPRESSED = "suppressed";

/*
/************************************************************
Expand Down Expand Up @@ -82,6 +83,7 @@ public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) t

Object throwable = null;
Object[] pending = null;
Throwable[] suppressed = null;
int pendingIx = 0;

for (; !p.hasToken(JsonToken.END_OBJECT); p.nextToken()) {
Expand Down Expand Up @@ -120,6 +122,14 @@ public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) t
continue;
}
}

// Maybe it's "suppressed"?
final boolean isSuppressed = PROP_NAME_SUPPRESSED.equals(propName);
if (isSuppressed) {
suppressed = p.readValueAs(Throwable[].class);
continue;
}

// Things marked as ignorable should not be passed to any setter
if ((_ignorableProps != null) && _ignorableProps.contains(propName)) {
p.skipChildren();
Expand Down Expand Up @@ -156,6 +166,14 @@ public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) t
}
}
}

if (suppressed != null && throwable instanceof Throwable) {
Throwable t = (Throwable) throwable;
for (Throwable s : suppressed) {
t.addSuppressed(s);
}
}

return throwable;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import com.fasterxml.jackson.annotation.*;

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;

/**
* Unit tests for verifying that simple exceptions can be deserialized.
Expand Down Expand Up @@ -130,6 +133,47 @@ public void testExceptionCauseDeserialization() throws IOException
_assertEquality(exp.getCause().getStackTrace(), act.getCause().getStackTrace());
}


public void testSuppressedGenericThrowableDeserialization() throws IOException
{
ObjectMapper mapper = new ObjectMapper();

final IOException exp = new IOException("the outer exception");
exp.addSuppressed(new Throwable("the suppressed exception"));

final String value = mapper.writeValueAsString(exp);
final IOException act = mapper.readValue(value, IOException.class);

assertNotNull(act.getSuppressed());
assertEquals(1, act.getSuppressed().length);
assertEquals(exp.getSuppressed()[0].getMessage(), act.getSuppressed()[0].getMessage());
_assertEquality(exp.getSuppressed()[0].getStackTrace(), act.getSuppressed()[0].getStackTrace());
}

public void testSuppressedTypedExceptionDeserialization() throws IOException
{
PolymorphicTypeValidator typeValidator = BasicPolymorphicTypeValidator.builder()
.allowIfSubTypeIsArray()
.allowIfSubType(Throwable.class)
.build();

ObjectMapper mapper = JsonMapper.builder()
.activateDefaultTyping(typeValidator, ObjectMapper.DefaultTyping.NON_FINAL)
.build();

final IOException exp = new IOException("the outer exception");
exp.addSuppressed(new IllegalArgumentException("the suppressed exception"));

final String value = mapper.writeValueAsString(exp);
final IOException act = mapper.readValue(value, IOException.class);

assertNotNull(act.getSuppressed());
assertEquals(1, act.getSuppressed().length);
assertEquals(IllegalArgumentException.class, act.getSuppressed()[0].getClass());
assertEquals(exp.getSuppressed()[0].getMessage(), act.getSuppressed()[0].getMessage());
_assertEquality(exp.getSuppressed()[0].getStackTrace(), act.getSuppressed()[0].getStackTrace());
}

private void _assertEquality(StackTraceElement[] exp, StackTraceElement[] act) {
assertEquals(exp.length, act.length);
for (int i = 0; i < exp.length; i++) {
Expand Down

0 comments on commit d14ebdc

Please sign in to comment.