我如何创建一个 ArchUnit 规则来验证所有抛出的异常都继承自特定的自定义异常?

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<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);

运行 这条规则 returns 正确(JUnit 测试通过),即使我的代码抛出的异常也不是 CustomException。

我已经测试了检测构造函数具有可分配给 Throwable 的所有者的规则部分:

private static final ArchCondition<JavaClass> THROWS_NON_CUSTOM_EXCEPTION =    
   callCodeUnitWhere( 
      target(is(constructor()))
         .and(
            originOwner( 
               is(assignableTo(Throwable.class))
            )
         )
   );

这正确 returns 代码中创建任何 Throwable 的每个地方。

问题似乎出在我的代码中,它试图找到不能分配给 CustomException 的所有者:

   private static final ArchCondition<JavaClass> THROWS_NON_CUSTOM_EXCEPTION = callCodeUnitWhere( 
      target(is(constructor()))
         .and(
            originOwner( 
               is(not(assignableTo(CustomException.class)))
            )
         )
   );

这 returns 每个构造函数,甚至是那些可分配给 CustomException 的异常。

在 ArchUnit 中编写规则的正确方法是什么 returns 每个调用其所有者可分配给 Throwable 的构造函数的代码单元,并且 不可 可分配给自定义异常?

我认为您只需要组合已有的部分即可。以下代码对我有用:

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 位于分析范围内,您将需要排除 class:noClasses().that(not(belongToAnyOf(BaseException.class)))