{"record":{"id":"ccec7c9371a3e1a4","repo":"YunaiV/yudao-cloud","slug":"invalid-interval","errorCode":null,"errorMessage":"Invalid interval: {}","messagePattern":"Invalid interval: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java","lineNumber":338,"sourceCode":"            case QUARTER:\n                while (startTime.isBefore(endTime)) {\n                    int quarterOfYear = getQuarterOfYear(startTime);\n                    LocalDateTime quarterEnd = quarterOfYear == 4\n                            ? startTime.with(TemporalAdjusters.lastDayOfYear()).plusDays(1).minusNanos(1)\n                            : startTime.withMonth(quarterOfYear * 3 + 1).withDayOfMonth(1).minusNanos(1);\n                    timeRanges.add(new LocalDateTime[]{startTime, quarterEnd});\n                    startTime = quarterEnd.plusNanos(1);\n                }\n                break;\n            case YEAR:\n                while (startTime.isBefore(endTime)) {\n                    LocalDateTime endOfYear = startTime.with(TemporalAdjusters.lastDayOfYear()).plusDays(1).minusNanos(1);\n                    timeRanges.add(new LocalDateTime[]{startTime, endOfYear});\n                    startTime = endOfYear.plusNanos(1);\n                }\n                break;\n            default:\n                throw new IllegalArgumentException(\"Invalid interval: \" + interval);\n        }\n        // 3. 兜底，最后一个时间，需要保持在 endTime 之前\n        LocalDateTime[] lastTimeRange = CollUtil.getLast(timeRanges);\n        if (lastTimeRange != null) {\n            lastTimeRange[1] = endTime;\n        }\n        return timeRanges;\n    }\n\n    /**\n     * 获取从开始日期起的日期列表\n     *\n     * @param startDate 开始日期\n     * @param days 天数\n     * @return 日期列表，包含开始日期\n     */\n    public static List<LocalDate> getDateList(LocalDate startDate, int days) {\n        List<LocalDate> dateList = new ArrayList<>(days);","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/YunaiV/yudao-cloud/blob/477be9dd49ab7223a972a6abdff0684d6423dec3/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java#L320-L356","documentation":"LocalDateTimeUtils.addTimeRange loops over an interval enum splitting a time span into day/week/month/quarter/year buckets. The switch's default branch throws IllegalArgumentException for any enum constant outside those five — this is a coding/extension error, not a data error.","triggerScenarios":"Calling the method with an interval enum value such as HOUR or MINUTE (present in many interval enums but not handled here), or after someone adds a new constant (e.g. HALF_YEAR) to the enum without extending the switch.","commonSituations":"Reusing a generic TimeIntervalEnum across features where chart aggregation only supports day..year; adding enum constants in a PR without touching this utility; copy-pasting the util for a new report and passing an unsupported granularity.","solutions":["Pass only DAY, WEEK, MONTH, QUARTER or YEAR to this method.","If a coarser/finer bucket is needed, add an explicit case instead of reusing an unhandled constant.","Convert before calling: e.g. aggregate HOUR data upstream and call with DAY.","Add a unit test enumerating all enum constants against this method so new constants fail the build, not production."],"exampleFix":"// before\nList<LocalDateTime[]> ranges = LocalDateTimeUtils.addTimeRange(start, end, IntervalEnum.HOUR);\n\n// after\nList<LocalDateTime[]> ranges = LocalDateTimeUtils.addTimeRange(start, end, IntervalEnum.DAY);","handlingStrategy":"type-guard","validationCode":"Set<IntervalEnum> supported = EnumSet.of(DAY, WEEK, MONTH, QUARTER, YEAR);\nif (!supported.contains(interval)) throw new IllegalArgumentException(\"Unsupported interval: \" + interval);","typeGuard":"static boolean isSupportedInterval(IntervalEnum i) {\n    return i == IntervalEnum.DAY || i == IntervalEnum.WEEK || i == IntervalEnum.MONTH\n        || i == IntervalEnum.QUARTER || i == IntervalEnum.YEAR;\n}","tryCatchPattern":null,"preventionTips":["Expose only supported granularities from API DTOs (enum validation on input)","Add an exhaustive-switch unit test over all enum constants so new constants fail CI"],"tags":["java","date","enum","switch","validation"],"backgroundTag":null,"analyzedSha":"477be9dd49ab7223a972a6abdff0684d6423dec3","analyzedAt":"2026-08-14T13:35:31.121Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}