You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改ArchUnit测试以检测log.error是否包含Throwable参数?

问题分析与解决方案

问题根源

你的测试代码错误地检查了方法的形参类型,而当使用log.error("xxx", param1, e)这种多参数写法时,实际调用的是Log4j2的error(String format, Object... params)可变参数重载。该方法的形参列表是[String, Object[]],自然无法匹配Throwable类型,导致测试误判合规代码为违规。

修改后的测试代码

void errors_should_be_logged_with_context() {
    ArchRule rule = noClasses()
            .should(callMethodWhere(
                    target(name("error")).and(target(owner(assignableTo(Logger.class))))
                    .and(arguments(new DescribedPredicate<>("error logs missing Throwable as last argument") {
                        @Override
                        public boolean test(List<JavaLiteral> arguments) {
                            // 禁止两种违规情况:参数数量≤1,或最后一个参数不是Throwable
                            if (arguments.size() <= 1) {
                                return true;
                            }
                            JavaLiteral lastArgument = arguments.get(arguments.size() - 1);
                            return !lastArgument.getType().isAssignableTo(Throwable.class);
                        }
                    }))
            ).as("All error logs must include a Throwable as the last argument");
    rule.check(ALL_CLASSES);
}

关键调整说明

  • 替换rawParameterTypes()为arguments():直接获取日志调用时的实参列表,而非方法定义的形参;
  • 优化判定逻辑:仅当以下任意一种情况成立时,判定为违规:
    1. log.error调用的参数数量≤1(仅传了日志消息,无上下文或异常);
    2. 调用的最后一个实参不是Throwable类型;
  • 覆盖所有合规场景:无论是直接调用带Throwable形参的重载(如log.error("msg", e)),还是通过可变参数传递异常(如log.error("msg: {}", param, e)),都会被识别为合规调用。

内容的提问来源于stack exchange,提问作者Uros K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 20:55:40