异常或者error code汇总:https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_calls_concepts_core_data_objects.htm

做项目的时候有很多异常是我们经常遇到的:

  1.空指针异常;

  2.死锁或者超时;

  3.级联删除时无级联表操作权限导致删除失败;

  4.一次请求查询超过50000条数据;

  5.查询时偏移量超过2000;

  6.不满足Validation Rule条件;

  7.必填字段为空;

  8.unique字段记录添加重复。

上述问题很多可以封装公共方法来捕获异常并且返回友好的提示信息,免得将异常直接抛出,导致用户一头雾水。

此篇针对常见异常进行最基本的封装,方便后期项目有类似需求可以直接使用。

ErrorHelper:此类封装的getUserFriendlyMessage方法用于当程序操作出现异常时,可以返回友好的错误提示信息,第一个参数是errormessage,即error.getMessage(),第二个参数为sObject的API Name。

 global with sharing class ErrorHelper {
private static final String NULL_POINTER_EXCEPTION = '空指针错误';
private static final String RECORD_ALREADY_INPROCESS = '记录已经被锁定';
private static final String RECORD_OVER_LIMIT = '查询最多只能50000条,请输入搜索条件重新搜索';
private static final String RECORD_OFFSET_OVER_LIMIT = '数据最多只能查询当前检索条件前2000条,请更改检索条件重试';
private static final String RECORD_ALREADY_IN_PROCESS = '当前记录已经在流程中,如有问题,请与管理员联系';
public static String getUserFriendlyMessage(String msg,String sObjectName) {
String errorMessage;
//空指针错误:System.NullPointerException: Attempt to de-reference a null object
if(msg.contains('NullPointerException')){
errorMessage = NULL_POINTER_EXCEPTION;
}
//死锁或者超时
else if(msg.contains('UNABLE_TO_LOCK')){
errorMessage = RECORD_ALREADY_INPROCESS;
}
//级联删除,没有当前表或者关联表权限导致的错误
else if(msg.contains('DELETE_REQUIRED_ON_CASCADE')) { }
//查询50001
else if(msg.contains('Too many query rows')) {
errorMessage = RECORD_OVER_LIMIT;
}
//offset 超过2000
else if(msg.contains('Maximum SOQL offset allowed is 2000')) {
errorMessage = RECORD_OFFSET_OVER_LIMIT;
}
//当前记录已经在审批流中
else if(msg.contains('ALREADY_IN_PROCESS')) {
errorMessage = RECORD_ALREADY_IN_PROCESS;
}
//Validation Rule失败
//eg: Update failed. First exception on row 0 with id a052800000BvtqEAAR; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, 商品价格不能为空且必须大于0.: [GoodsPrice__c]
else if (msg.contains('FIELD_CUSTOM_VALIDATION_EXCEPTION')){
errorMessage = getUserFriendlyMessage4ValidationException(msg,sObjectName);
}
//必填字段
//eg:Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Company_Name__c]: [Company_Name__c]
else if(msg.contains('REQUIRED_FIELD_MISSING')){
errorMessage = getUserFriendlyMessage4RequiredField(msg,sObjectName);
}
//对于unique的字段进行相同值插入会报此种错误:System.DmlException: Insert failed. First exception on row 0; first error: DUPLICATE_VALUE, duplicate value found: Company_Code_Unique__c duplicates value on record with id: a032800000KOlEr: [] else if(msg.contains('DUPLICATE_VALUE')) {
errorMessage = getUserFriendlyMessage4DuplicateValue(msg,sObjectName);
}
return errorMessage;
} /**
*针对unique字段添加重复值的异常获取友好的message
*@param msg : 异常信息 eg : System.DmlException: Insert failed. First exception on row 0; first error: DUPLICATE_VALUE, duplicate value found: Company_Code_Unique__c duplicates value on record with id: a032800000KOlEr: []
*@param sObjectName : sObject的API Name
*@return
*/
private static String getUserFriendlyMessage4DuplicateValue(String msg,String sObjectName) {
String errorMessage = msg;
Integer pointer;
String fieldName;
if(!msg.contains('DUPLICATE_VALUE')) {
return errorMessage;
}
pointer = errorMessage.indexOf('DUPLICATE_VALUE') + 16;
if(pointer > -1) {
errorMessage = errorMessage.mid(pointer, errorMessage.length());
}
pointer = errorMessage.indexOf('duplicates');
if(pointer > -1) {
errorMessage = errorMessage.mid(0,pointer);
}
pointer = errorMessage.indexOf(':') + 1;
if(pointer > -1) {
fieldName = errorMessage.mid(pointer,errorMessage.length()).trim();
Schema.DescribeFieldResult fieldResult = getSObjectFieldDescribeResult(sObjectName,fieldName);
if(fieldResult != null) {
fieldName = fieldResult.getLabel();
}
}
errorMessage = errorMessage.mid(0,pointer) + fieldName;
return errorMessage;
} /**
*针对Validation Rule的异常获取友好的message
*@param msg : 异常消息 eg: Update failed. First exception on row 0 with id a052800000BvtqEAAR; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, 商品价格不能为空且必须大于0.: [GoodsPrice__c]
*@param sObjectName : sObject的API Name
*@return 返回有问题的field labe + : + error message (eg : GoodsPrice : 商品价格不能为空且必须大于0.)
*/
private static String getUserFriendlyMessage4ValidationException(String msg,String sObjectName){
String errorMessage = msg;
Integer pointer;
String fieldName;
if (msg.contains('FIELD_CUSTOM_VALIDATION_EXCEPTION')){
pointer = errorMessage.indexOf('FIELD_CUSTOM_VALIDATION_EXCEPTION,') + 34;
errorMessage = errorMessage.mid(pointer, errorMessage.length());
} else {
return msg;
}
pointer = errorMessage.indexOf('\n');
if(pointer > -1){
errorMessage = errorMessage.mid(0, pointer);
}
pointer = errorMessage.indexOf(':');
if(pointer > -1){
//去除error message中的 []
fieldName = errorMessage.mid(pointer + 1,errorMessage.length()-1).remove('[').remove(']').trim();
errorMessage = errorMessage.mid(0, pointer);
}
if(fieldName != null) {
Schema.DescribeFieldResult fieldDescribeResult = getSObjectFieldDescribeResult(sObjectName,fieldName);
if(fieldDescribeResult != null) {
errorMessage = fieldDescribeResult.getLabel() + ' : ' + errorMessage;
}
}
return errorMessage;
} /**
* 针对必填字段获取友好的message
* @param msg : 异常消息 eg: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Company_Name__c]: [Company_Name__c]
* @param sObjectName : sObject的API Name
* @return : 友好消息 eg : Required fields are missing: Company Name (field label name)
*/
private static String getUserFriendlyMessage4RequiredField(String msg,String sObjectName){
String errorMessage = msg;
if(!errorMessage.contains('first error:')) {
return errorMessage;
}
Integer pointer;
String fieldName;
//获取first error 以后的message信息
pointer = errorMessage.indexOf('first error:') + 12;
errorMessage = errorMessage.mid(pointer, errorMessage.length());
if(pointer > -1){
pointer = errorMessage.indexOf(',') + 1;
errorMessage = errorMessage.mid(pointer, errorMessage.length());
} pointer = errorMessage.indexOf(']:');
if(pointer > -1){
errorMessage = errorMessage.mid(0, pointer + 1);
}
fieldName = errorMessage.mid(errorMessage.indexOf('[') + 1,errorMessage.indexOf(']')-errorMessage.indexOf('[')-1).trim();
if(fieldName != null) {
Schema.DescribeFieldResult fieldResult = getSObjectFieldDescribeResult(sObjectName,fieldName);
if(fieldResult != null) {
fieldName = fieldResult.getLabel();
}
}
pointer = errorMessage.indexOf('[');
if(pointer > -1){
errorMessage = errorMessage.mid(0, pointer);
}
errorMessage += fieldName;
return errorMessage;
} /*
* 通过sObject名称以及field名称获取field相关describe result信息
* @param sObjectName object的api name
* @param fieldName field的api name
* @return 此field的describe result
*/
private static Schema.DescribeFieldResult getSObjectFieldDescribeResult(String sObjectName,String fieldName) {
List<Schema.DescribeSObjectResult> sObjectResultList = Schema.describeSObjects(new String[]{sObjectName});
if(sObjectResultList == null || sObjectResultList.size() == 0) {
return null;
} else {
Schema.DescribeSObjectResult sObjectResult = sObjectResultList.get(0);
Map<String,SObjectField> maps = sObjectResult.fields.getMap();
Schema.SObjectField sObjectField = maps.get(fieldName);
if(sObjectField == null) {
return null;
} else {
Schema.DescribeFieldResult fieldDescribeResult = sObjectField.getDescribe();
return fieldDescribeResult;
}
}
} }

使用演示:

1.Unique字段插入重复

2.必填字段为空

3.Validation Rule未通过

总结:此篇主要封装简单的异常的友好显示。当前很多常量都放在了程序里,建议放在custom label中,然后对相关进行translate,这样可以保证国际化使用,否则现在language为英文可以,中文使用会有问题,有用到的可以自行优化。

salesforce 零基础学习(五十四)常见异常友好消息提示的更多相关文章

  1. salesforce 零基础学习(十六)Validation Rules & Date/time

    上一篇介绍的内容为Formula,其中的Date/time部分未指出,此篇主要介绍Date/time部分以及Validation rules. 本篇参考PDF: Date/time:https://r ...

  2. salesforce 零基础学习(十九)Permission sets 讲解及设置

    Permission sets以及Profile是常见的设置访问权限的方式. Profile规则为'who see what'.通过Profile可以将一类的用户设置相同的访问权限.对于有着相同Pro ...

  3. salesforce 零基础学习(十八)WorkFlow介绍及用法

    说起workflow大家肯定都不陌生,这里简单介绍一下salesforce中什么情况下使用workflow. 当你分配许多任务,定期发送电子邮件,记录修改时,可以通过自动配置workflow来完成以上 ...

  4. salesforce零基础学习(九十四)classic下pagelayout引入的vf page弹出内容更新此page layout

    我们在classic环境中,有时针对page layout不能实现的地方,可以引入 一个vf page去增强标准的 page layout 功能,有时可能要求这个 vf page的部分修改需要更新此 ...

  5. salesforce 零基础学习(五十二)Trigger使用篇(二)

    第十七篇的Trigger用法为通过Handler方式实现Trigger的封装,此种好处是一个Handler对应一个sObject,使本该在Trigger中写的代码分到Handler中,代码更加清晰. ...

  6. salesforce零基础学习(八十)使用autoComplete 输入内容自动联想结果以及去重实现

    项目中,我们有时候会需要实现自动联想功能,比如我们想输入用户或者联系人名称,去联想出系统中有的相关的用户和联系人,当点击以后获取相关的邮箱或者其他信息等等.这种情况下可以使用jquery ui中的au ...

  7. salesforce零基础学习(八十九)使用 input type=file 以及RemoteAction方式上传附件

    在classic环境中,salesforce提供了<apex:inputFile>标签用来实现附件的上传以及内容获取.salesforce 零基础学习(二十四)解析csv格式内容中有类似的 ...

  8. salesforce零基础学习(一百零五)Change Data Capture

    本篇参考: https://developer.salesforce.com/docs/atlas.en-us.232.0.api_streaming.meta/api_streaming/using ...

  9. salesforce零基础学习(一百一十)list button实现的一些有趣事情

    本篇参考: salesforce零基础学习(九十五)lightning out https://developer.salesforce.com/docs/component-library/docu ...

随机推荐

  1. 笔记:Binder通信机制

    TODO: 待修正 Binder简介 Binder是android系统中实现的一种高效的IPC机制,平常接触到的各种XxxManager,以及绑定Service时都在使用它进行跨进程操作. 它的实现基 ...

  2. 百度 flash html5自切换 多文件异步上传控件webuploader基本用法

    双核浏览器下在chrome内核中使用uploadify总有302问题,也不知道如何修复,之所以喜欢360浏览器是因为帮客户控制渲染内核: 若页面需默认用极速核,增加标签:<meta name=& ...

  3. 23种设计模式--责任链模式-Chain of Responsibility Pattern

    一.责任链模式的介绍 责任链模式用简单点的话来说,将责任一步一步传下去,这就是责任,想到这个我们可以相当击鼓传花,这个是为了方便记忆,另外就是我们在项目中经常用到的审批流程等这一类的场景时我们就可以考 ...

  4. [原] KVM 虚拟化原理探究 —— 目录

    KVM 虚拟化原理探究 -- 目录 标签(空格分隔): KVM KVM 虚拟化原理探究(1)- overview KVM 虚拟化原理探究(2)- QEMU启动过程 KVM 虚拟化原理探究(3)- CP ...

  5. Performance Monitor4:监控SQL Server的IO性能

    SQL Server的IO性能受到物理Disk的IO延迟和SQL Server内部执行的IO操作的影响.在监控Disk性能时,最主要的度量值(metric)是IO延迟,IO延迟是指从Applicati ...

  6. FreeMarker:怎么使用

    第一个FreeMarker程序 1. 建立一个普通的java项目:testFreeMarker 2. 引入freemarker.jar包 3. 在项目目录下建立模板目录:templates 4. 在t ...

  7. 微信小程序监控 - HotApp统计

    HotApp小程序统计,第一个专业的微信第三方小程序监控统计工具 1.什么是HotApp小程序统计 HotApp小程序统计是第一个微信第三方小程序统计工具,就像做android 和 ios开发的人知道 ...

  8. Express 教程 01 - 入门教程之经典的Hello World

    目录: 前言 一.Express?纳尼?! 二.开始前的准备工作 三.测试安装之经典的Hello World 四.使用express(1)来生成一个应用程序 五.说明 前言: 本篇文章是建立在Node ...

  9. linux常用查看硬件设备信息命令

    转载:http://blog.chinaunix.net/uid-26782198-id-3242120.html # uname -a               # 查看内核/操作系统/CPU信息 ...

  10. [转]Java常用工具类集合

    转自:http://blog.csdn.net/justdb/article/details/8653166 数据库连接工具类——仅仅获得连接对象 ConnDB.java package com.ut ...