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

Salesforce Apex超级徽章任务代码报错:List索引越界求助

Salesforce超级徽章任务异常:System.ListException: List index out of bounds

问题背景

备考首个Salesforce超级徽章,在「Automate record creation」任务中编写了Case触发器及MaintenanceRequestHelper辅助类,意图实现:当Case状态从非Closed改为Closed且类型为Repair或Routine Maintenance时,自动创建维护请求记录。执行时触发System.ListException: List index out of bounds: 1异常,异常位于MaintenanceRequestHelper类的requestDue方法第64行。

原代码

Trigger Helper代码

public with sharing class MaintenanceRequestHelper {
    public static void createMaintenanceRequests(List<Case> newData, Map<Id, Case> oldData) {
        
        Set<Id> casesIds = new Set<Id>();
        for(Case c : newData){
            if(oldData.get(c.Id).Status != 'Closed' && c.Status == 'Closed'){
                if(c.Type == 'Repair' || c.Type == 'Routine Maintenance'){
                    casesIds.add(c.Id);
                }
            }
        }
        
        Double minMaintenanceCycle = requestDue(casesIds);
        Integer daysToAdd = Math.round(minMaintenanceCycle);
        Date today = System.today();
        
        List<Case> newCases = new List<Case>();
        
        for(Case cc : [SELECT Id, ParentId, Vehicle__c, Vehicle__r.Name, (SELECT Equipment__c, Maintenance_Request__c, Quantity__c FROM Equipment_Maintenance_Items__r) FROM Case WHERE Id IN :casesIds]){
            Case nc = new Case();
            nc.ParentId = cc.Id;
            nc.Status = 'New';
            nc.Subject = 'Maintenance Request for ' + cc.Vehicle__r.Name;
            nc.Type = 'Routine Maintenance';
            nc.Vehicle__c = cc.Vehicle__c;
           
            for (Equipment_Maintenance_Item__c eq : cc.Equipment_Maintenance_Items__r) {
                Equipment_Maintenance_Item__c newEq = new Equipment_Maintenance_Item__c();
                newEq.Equipment__c = eq.Equipment__c;
                newEq.Maintenance_Request__c = eq.Maintenance_Request__c;
                newEq.Quantity__c = eq.Quantity__c;
                nc.Equipment_Maintenance_Items__r.add(newEq);
            }

            nc.Date_Reported__c = today;
            nc.Date_Due__c = today.addDays(daysToAdd);
            newCases.add(nc);
        }

        try {
            insert newCases;
        } catch (DMLException e) {
            System.debug(e);
        }

    }

    public static Double requestDue(Set<Id> validIds){
        List<Case> cases = [SELECT (SELECT Equipment__c, Maintenance_Request__c, Quantity__c FROM Equipment_Maintenance_Items__r) FROM Case WHERE Id IN :validIds];
        
        Set<Id> equipIds = new Set<Id>();
        for (Case c : cases) {
            for (Equipment_Maintenance_Item__c emi : c.Equipment_Maintenance_Items__r) {
                equipIds.add(emi.Equipment__c);
            }
        }
        List<Double> maintenanceCycles = new List<Double>();
        List<Product2> equipmentList = [SELECT Maintenance_Cycle__c FROM Product2 WHERE Id IN :equipIds];
        for (Product2 p : equipmentList) {
            maintenanceCycles.add(p.Maintenance_Cycle__c);
        }

        maintenanceCycles.sort();
        return maintenanceCycles[0];
    }
}

Trigger代码

trigger MaintenanceRequest on Case (before update, after update) {
    if(Trigger.isUpdate && Trigger.isAfter){
        MaintenanceRequestHelper.createMaintenanceRequests(Trigger.New, Trigger.OldMap);
    }
}

错误信息

There was an unexpected error in your org which is preventing this assessment check from completing: System.DmlException: Update failed. First exception on row 0 with id 5008b00002KYlQbAAL; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, MaintenanceRequest: execution of AfterUpdate caused by: System.ListException: List index out of bounds: 1 Class.MaintenanceRequestHelper.requestDue: line 64, column 1 Class.MaintenanceRequestHelper.createMaintenanceRequests: line 13, column 1 Trigger.MaintenanceRequest: line 3, column 1: []

原因分析

  1. 直接触发点:requestDue方法中,当maintenanceCycles列表为空时,执行return maintenanceCycles[0]会触发索引越界异常。错误信息中显示的索引1为行号对应偏差,本质是列表无元素时访问索引导致的异常。
  2. 触发场景:
    • 符合条件的Case未关联任何Equipment_Maintenance_Item__c记录,导致equipIds为空集合,查询Product2返回空列表,maintenanceCycles无元素。
    • 关联的Equipment_Maintenance_Item__c对应的Product2记录中,Maintenance_Cycle__c字段为空值,添加到列表时未做过滤,最终列表无有效数值。
  3. 额外隐患:createMaintenanceRequests方法中未判断casesIds是否为空,直接调用requestDue,会导致无意义的查询和异常触发。

解决建议

1. 处理空列表场景,避免索引越界

修改requestDue方法,先判断maintenanceCycles是否为空,返回默认值或抛出明确提示(根据业务需求选择):

public static Double requestDue(Set<Id> validIds){
    List<Case> cases = [SELECT (SELECT Equipment__c, Maintenance_Request__c, Quantity__c FROM Equipment_Maintenance_Items__r) FROM Case WHERE Id IN :validIds];
    
    Set<Id> equipIds = new Set<Id>();
    for (Case c : cases) {
        for (Equipment_Maintenance_Item__c emi : c.Equipment_Maintenance_Items__r) {
            equipIds.add(emi.Equipment__c);
        }
    }
    List<Double> maintenanceCycles = new List<Double>();
    List<Product2> equipmentList = [SELECT Maintenance_Cycle__c FROM Product2 WHERE Id IN :equipIds];
    for (Product2 p : equipmentList) {
        // 过滤空值,避免添加无效数据
        if(p.Maintenance_Cycle__c != null){
            maintenanceCycles.add(p.Maintenance_Cycle__c);
        }
    }

    if(maintenanceCycles.isEmpty()){
        // 返回默认维护周期(比如7天,根据业务要求调整)
        return 7.0;
        // 或者如果不需要创建请求,可返回null,后续逻辑判断
        // return null;
    }
    
    maintenanceCycles.sort();
    return maintenanceCycles[0];
}

2. 前置判断,避免无意义执行

在createMaintenanceRequests方法中,先判断casesIds是否为空,再执行后续逻辑:

public static void createMaintenanceRequests(List<Case> newData, Map<Id, Case> oldData) {
    
    Set<Id> casesIds = new Set<Id>();
    for(Case c : newData){
        if(oldData.get(c.Id).Status != 'Closed' && c.Status == 'Closed'){
            if(c.Type == 'Repair' || c.Type == 'Routine Maintenance'){
                casesIds.add(c.Id);
            }
        }
    }
    
    // 无符合条件的Case时直接返回
    if(casesIds.isEmpty()){
        return;
    }
    
    Double minMaintenanceCycle = requestDue(casesIds);
    // 如果requestDue返回null,说明无有效维护周期,跳过创建
    if(minMaintenanceCycle == null){
        return;
    }
    Integer daysToAdd = Math.round(minMaintenanceCycle);
    Date today = System.today();
    
    List<Case> newCases = new List<Case>();
    
    for(Case cc : [SELECT Id, ParentId, Vehicle__c, Vehicle__r.Name, (SELECT Equipment__c, Maintenance_Request__c, Quantity__c FROM Equipment_Maintenance_Items__r) FROM Case WHERE Id IN :casesIds]){
        // 无关联设备时跳过创建
        if(cc.Equipment_Maintenance_Items__r.isEmpty()){
            continue;
        }
        
        Case nc = new Case();
        nc.ParentId = cc.Id;
        nc.Status = 'New';
        nc.Subject = 'Maintenance Request for ' + cc.Vehicle__r.Name;
        nc.Type = 'Routine Maintenance';
        nc.Vehicle__c = cc.Vehicle__c;
       
        for (Equipment_Maintenance_Item__c eq : cc.Equipment_Maintenance_Items__r) {
            Equipment_Maintenance_Item__c newEq = new Equipment_Maintenance_Item__c();
            newEq.Equipment__c = eq.Equipment__c;
            newEq.Maintenance_Request__c = eq.Maintenance_Request__c;
            newEq.Quantity__c = eq.Quantity__c;
            nc.Equipment_Maintenance_Items__r.add(newEq);
        }

        nc.Date_Reported__c = today;
        nc.Date_Due__c = today.addDays(daysToAdd);
        newCases.add(nc);
    }

    try {
        insert newCases;
    } catch (DMLException e) {
        System.debug(e);
    }

}

3. 业务数据校验

确保测试用的Case关联了有效的Equipment_Maintenance_Item__c记录,且对应的Product2记录的Maintenance_Cycle__c字段已设置数值。

内容的提问来源于stack exchange,提问作者Rafael Moraes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 14:47:01