One of my architecture rules is that all exceptions thrown by the application code must be either CustomException, or a subclass of CustomException.
I am having difficulty writing this rule in ArchUnit. What I have currently is the following:
private static final ArchCondition<JavaClass> THROWS_NON_CUSTOM_EXCEPTION = callCodeUnitWhere(
target(is(constructor()))
.and(
originOwner(
is(assignableTo(Throwable.class))
.and(not(assignableTo(CustomException.class)))
)
)
);
@ArchTest public static final ArchRule noNonCustomExceptions = noClasses()
.should(THROWS_NON_CUSTOM_EXCEPTION);
Running this rule returns true (the JUnit test passes) even though I have code that throws an exception that is not also a CustomException.
I have tested the part of the rule that detects that the constructor has an owner that is assignable to Throwable:
private static final ArchCondition<JavaClass> THROWS_NON_CUSTOM_EXCEPTION =
callCodeUnitWhere(
target(is(constructor()))
.and(
originOwner(
is(assignableTo(Throwable.class))
)
)
);
This correctly returns every place in the code that creates any Throwable.
The problem seems to be in my code that attempts to find owners that are NOT assignable to CustomException:
private static final ArchCondition<JavaClass> THROWS_NON_CUSTOM_EXCEPTION = callCodeUnitWhere(
target(is(constructor()))
.and(
originOwner(
is(not(assignableTo(CustomException.class)))
)
)
);
This returns every constructor, even those for exceptions that are assignable to CustomException.
What is the proper way in ArchUnit to write a rule that returns every code unit that calls a constructor whose owner is assignable to Throwable, and not assignable to CustomException?