英文:
How do I create an ArchUnit rule to verify all exceptions thrown inherit from a specific custom exception?
问题
以下是您提供的代码部分的翻译:
我的架构规则之一是应用程序代码抛出的所有异常必须是CustomException,或者是CustomException的子类。
我在使用ArchUnit编写这个规则时遇到了困难。我目前的代码如下所示:
private static final ArchCondition
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);
运行这个规则返回true(JUnit测试通过),即使我有抛出不是CustomException的异常的代码。
我已经测试了检测构造函数所有者是否可分配给Throwable的规则的部分:
private static final ArchCondition
callCodeUnitWhere(
target(is(constructor()))
.and(
originOwner(
is(assignableTo(Throwable.class))
)
)
);
这正确地返回了代码中创建任何Throwable的每个位置。
问题似乎出现在我试图找到所有者不可分配给CustomException的代码部分:
private static final ArchCondition
target(is(constructor()))
.and(
originOwner(
is(not(assignableTo(CustomException.class)))
)
)
);
这返回了每个构造函数,甚至是那些可分配给CustomException的异常的构造函数。
在ArchUnit中,编写一个规则以返回调用所有者可分配给Throwable的构造函数的每个代码单元,同时*不*可分配给CustomException的方法是什么?
英文:
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?
答案1
得分: 2
我认为你只需要将你已经拥有的部分组合起来。以下的代码对我有效:
noClasses().should().callCodeUnitWhere(
JavaCall.Predicates.target(
AccessTarget.Predicates.constructor()
.and(AccessTarget.Predicates.declaredIn(JavaClass.Predicates.assignableTo(Throwable.class)))
.and(DescribedPredicate.not(AccessTarget.Predicates.declaredIn(JavaClass.Predicates.assignableTo(BaseException.class))))
)
);
如果你的 BaseException
在分析的范围内,你需要排除那个类:noClasses().that(not(belongToAnyOf(BaseException.class)))
。
英文:
I think you just need to combine the pieces that you already have. The following code works for me:
noClasses().should().callCodeUnitWhere(
JavaCall.Predicates.target(
AccessTarget.Predicates.constructor()
.and(AccessTarget.Predicates.declaredIn(JavaClass.Predicates.assignableTo(Throwable.class)))
.and(DescribedPredicate.not(AccessTarget.Predicates.declaredIn(JavaClass.Predicates.assignableTo(BaseException.class))))
)
);
If your BaseException
resides in the analyzed scope you will need to exclude that class: noClasses().that(not(belongToAnyOf(BaseException.class)))
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论