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

Salesforce Contact触发器遇System.FinalException,自定义报错失效求助

解决Salesforce触发器System.FinalException错误方案

错误原因

你遇到的System.FinalException: SObject row does not allow errors,核心问题是你在查询出来的Contact实例上调用了addError方法。Salesforce规定,只有触发器上下文里的SObject(比如Trigger.new、Trigger.old)才能添加错误提示,直接查询出来的记录是独立副本,不属于触发上下文,因此不允许调用addError。

另外你的代码还有两个潜在问题:

  • 触发器中用[SELECT ... WHERE id IN :Trigger.new]查询返回的是列表,但你用单个Contact变量接收,批量处理时会直接报错
  • 处理器是单条记录处理逻辑,不符合Salesforce批量处理的最佳实践,容易触发SOQL查询次数限制

修正后的代码

触发器代码

trigger ContactTrigger on Contact (before update) {
    if(Trigger.isBefore && Trigger.isUpdate){
        ContactTriggerHandler.checkPricingLetterContacts(Trigger.new);
    }
}

处理器代码

public class ContactTriggerHandler {
    public static void checkPricingLetterContacts(List<Contact> contacts){
        // 批量收集所有待处理的Contact ID
        Set<Id> contactIds = new Set<Id>();
        for(Contact con : contacts){
            contactIds.add(con.Id);
        }
        
        // 一次查询所有关联"Pricing Letters"角色的Contact ID
        Set<Id> pricingLetterContactIds = new Set<Id>();
        for(AccountContactRelation acr : [SELECT ContactId 
                                           FROM AccountContactRelation 
                                           WHERE Roles INCLUDES ('Pricing Letters') 
                                           AND ContactId IN :contactIds]){
            pricingLetterContactIds.add(acr.ContactId);
        }
        
        // 遍历触发上下文的记录,给符合条件的Contact加错误提示
        for(Contact con : contacts){
            if(pricingLetterContactIds.contains(con.Id)){
                if(String.isBlank(con.MailingStreet)){
                    con.addError('Pricing Letter联系人的邮寄街道不能为空。');
                }
                if(String.isBlank(con.MailingCity)){
                    con.addError('Pricing Letter联系人的邮寄城市不能为空。');
                }
                if(String.isBlank(con.MailingPostalCode)){
                    con.addError('Pricing Letter联系人的邮寄邮政编码不能为空。');
                }
                if(String.isBlank(con.MailingState)){
                    con.addError('Pricing Letter联系人的邮寄州/省不能为空。');
                }
                if(String.isBlank(con.MailingCountry)){
                    con.addError('Pricing Letter联系人的邮寄国家/地区不能为空。');
                }
                if(String.isBlank(con.Email)){
                    con.addError('Pricing Letter联系人的邮箱地址不能为空。');
                }
            }
        }
    }
}

修改说明

  1. 触发器部分:直接将Trigger.new传入处理器,确保操作的是触发上下文的记录,避免查询副本导致的错误
  2. 处理器部分:
    • 批量收集Contact ID,一次完成所有关联AccountContactRelation的查询,符合Salesforce governor limits要求
    • 用Set存储符合条件的Contact ID,快速判断当前Contact是否属于目标角色
    • 替换==null为String.isBlank(),同时处理空字符串的情况(如用户输入空格)
    • 支持批量处理多条记录,适配触发器的批量执行场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 22:01:01