У меня есть следующая иерархия исключений:
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;
}
}
В моем классе рекомендаций по аспектам я ловлю исключение типа A
и задаю значение bypassable
. Обратите внимание, что я не перехватываю указанное c исключение типа 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;
}
}
}
Мне нужно сохранить информацию, которую можно перебрасывать, в базу данных как json, поэтому у меня есть этот класс сериализатора:
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)));
}
}
}
У меня проблема с атрибутом bypassable
. Хотя в коде аспекта я установил значение true
, в базе данных оно сохраняется как ложное.
Я думаю, это потому, что я каждый раз вызываю writeThrowable()
с причиной, и как-то подкласс C
ссылается на bypassable
как ложное. Когда я запускаю в режиме отладки, я получаю bypassable
написано дважды.
Я ищу помощь, чтобы правильно написать поле bypassable
. Я не уверен, как фильтровать причину, которая имеет true
. Возможно, нужно отфильтровать ссылку на суперкласс? Буду признателен за вашу помощь.
Json:
[
{
"cause": {
"cause": {
"class": "com.exception.C",
"message": "blah blah",
"bypassable": "true"
},
...