salesforce 零基础学习(五十四)常见异常友好消息提示
异常或者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 零基础学习(五十四)常见异常友好消息提示的更多相关文章
- salesforce 零基础学习(十六)Validation Rules & Date/time
上一篇介绍的内容为Formula,其中的Date/time部分未指出,此篇主要介绍Date/time部分以及Validation rules. 本篇参考PDF: Date/time:https://r ...
- salesforce 零基础学习(十九)Permission sets 讲解及设置
Permission sets以及Profile是常见的设置访问权限的方式. Profile规则为'who see what'.通过Profile可以将一类的用户设置相同的访问权限.对于有着相同Pro ...
- salesforce 零基础学习(十八)WorkFlow介绍及用法
说起workflow大家肯定都不陌生,这里简单介绍一下salesforce中什么情况下使用workflow. 当你分配许多任务,定期发送电子邮件,记录修改时,可以通过自动配置workflow来完成以上 ...
- salesforce零基础学习(九十四)classic下pagelayout引入的vf page弹出内容更新此page layout
我们在classic环境中,有时针对page layout不能实现的地方,可以引入 一个vf page去增强标准的 page layout 功能,有时可能要求这个 vf page的部分修改需要更新此 ...
- salesforce 零基础学习(五十二)Trigger使用篇(二)
第十七篇的Trigger用法为通过Handler方式实现Trigger的封装,此种好处是一个Handler对应一个sObject,使本该在Trigger中写的代码分到Handler中,代码更加清晰. ...
- salesforce零基础学习(八十)使用autoComplete 输入内容自动联想结果以及去重实现
项目中,我们有时候会需要实现自动联想功能,比如我们想输入用户或者联系人名称,去联想出系统中有的相关的用户和联系人,当点击以后获取相关的邮箱或者其他信息等等.这种情况下可以使用jquery ui中的au ...
- salesforce零基础学习(八十九)使用 input type=file 以及RemoteAction方式上传附件
在classic环境中,salesforce提供了<apex:inputFile>标签用来实现附件的上传以及内容获取.salesforce 零基础学习(二十四)解析csv格式内容中有类似的 ...
- salesforce零基础学习(一百零五)Change Data Capture
本篇参考: https://developer.salesforce.com/docs/atlas.en-us.232.0.api_streaming.meta/api_streaming/using ...
- salesforce零基础学习(一百一十)list button实现的一些有趣事情
本篇参考: salesforce零基础学习(九十五)lightning out https://developer.salesforce.com/docs/component-library/docu ...
随机推荐
- Sublime Text3安装JsHint
介绍 Sublime Text3使用jshint依赖Nodejs,SublimeLinter和Sublimelinter-jshint. NodeJs的安装省略. 安装SublimeLinter Su ...
- SQLServer地址搜索性能优化例子
这是一个很久以前的例子,现在在整理资料时无意发现,就拿出来再改写分享. 1.需求 1.1 基本需求: 根据输入的地址关键字,搜索出完整的地址路径,耗时要控制在几十毫秒内. 1.2 数据库地址表结构和数 ...
- Eclipse中启动tomcat报错java.lang.OutOfMemoryError: PermGen space的解决方法
有的项目引用了太多的jar包,或者反射生成了太多的类,异或有太多的常量池,就有可能会报java.lang.OutOfMemoryError: PermGen space的错误, 我们知道可以通过jvm ...
- Linux 常用命令(持续补充)
常用命令: command &:将进程放在后台执行 ctrl + z:暂停当前进程 并放入后台 jobs:查看当前后台任务 bg( %id):将任务转为后台执行 fg( %id):将任务调回前 ...
- 问题记录:EntityFramework 一对一关系映射
EntityFramework 一对一关系映射有很多种,比如主键作为关联,配置比较简单,示例代码: public class Teacher { public int Id { get; set; } ...
- Redis百亿级Key存储方案(转)
1 需求背景 该应用场景为DMP缓存存储需求,DMP需要管理非常多的第三方id数据,其中包括各媒体cookie与自身cookie(以下统称supperid)的mapping关系,还包括了supperi ...
- duang~免费的学习视频来啦:学霸君之全栈测试
学霸君向童鞋们推荐一款 同名学霸学习 视频教程 重点是完全免费收看学习噢!!! 今天 学霸君推荐腾讯课堂的学霸君之全栈测试 复制下方链接至腾讯课堂中报名学习 https://ke.qq.com/cou ...
- CSS3 @keyframes 动画
CSS3的@keyframes,它可以取代许多网页动画图像,Flash动画,和JAVAScripts. CSS3的动画属性 下面的表格列出了 @keyframes 规则和所有动画属性: 浏览器支持 表 ...
- jquery.each()
$(selector).each(function(index,element)) index - 选择器的 index 位置 element - 当前的元素(也可使用 "this" ...
- MySQL 优化之 ICP (index condition pushdown:索引条件下推)
ICP技术是在MySQL5.6中引入的一种索引优化技术.它能减少在使用 二级索引 过滤where条件时的回表次数 和 减少MySQL server层和引擎层的交互次数.在索引组织表中,使用二级索引进行 ...