I have the following exception Hierarchy:
public class C extends B {
public C(final String message) {
super(message);
}
}
public abstract class B extends A {
public B(final String message, final Throwable throwable) {
super(message, throwable);
}
public B(final String message) {
super(message);
}
}
public class A extends RuntimeException {
private boolean bypassable;
public A(final String message) {
super(message);
}
public A(final String message, final Throwable throwable) {
super(message, throwable);
}
public boolean isBypassable() {
return bypassable;
}
public void setBypassable(final boolean bypassable) {
this.bypassable = bypassable;
}
}
In my aspect advice class I am catching exception of type A
and setting the bypassable
value. Please note I am not catching the specific exception of type C
:
@Aspect
@Component
public class ByPassableExceptionAspect {
@Around("@annotation(...)")
public void handle(final ProceedingJoinPoint pjp) throws Throwable {
try {
pjp.proceed();
} catch (A exception) {
a.setByPassable(true);
}
} catch (Throwable t) {
throw t;
}
}
}
I need to persist the throwable information into database as json so I have this serializer class:
private class ThrowableJsonSerializer extends JsonSerializer<Throwable> {
@Override
public void serialize(final Throwable value,
final JsonGenerator gen,
final SerializerProvider serializers) throws IOException {
writeThrowable(someOtherMethod(value), gen);
}
private void writeThrowable(final Throwable value,
final JsonGenerator gen) throws IOException {
gen.writeStartObject();
gen.writeFieldName("class");
gen.writeString(value.getClass().getName());
writeBypassableIfExists(value, gen);
if (nonNull(value.getCause())) {
gen.writeFieldName("cause");
writeThrowable(value.getCause(), gen);
}
gen.writeEndObject();
}
private void writeBypassableIfExists(final Throwable throwable, final JsonGenerator gen) throws IOException {
final Field bypassableField = ReflectionUtils.findField(throwable.getClass(), "bypassable"); //Spring Framework ReflectionUtils
if (nonNull(bypassableField)) {
bypassableField.setAccessible(true);
gen.writeFieldName("bypassable");
gen.writeString(String.valueOf(ReflectionUtils.getField(bypassableField, throwable)));
}
}
}
The issue I have is with the bypassable
attribute. Although I set the value as true
in my aspect code, it gets persisted as false in the database.
I think it is because I am calling writeThrowable()
with cause each time and somehow the subclass C
has reference to bypassable
as false. When I run in debug, I get bypassable
is written twice.
I am looking for some help to write bypassable
field correctly. I am not sure how to filter on the Cause that has true
. Perhaps need to filter on the superclass reference one? Would appreciate your help.
Json:
[
{
"cause": {
"cause": {
"class": "com.exception.C",
"message": "blah blah",
"bypassable": "true"
},
...
Aucun commentaire:
Enregistrer un commentaire