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 ...
随机推荐
- ES6模块import细节
写在前面,目前浏览器对ES6的import支持还不是很好,需要用bable转译. ES6引入外部模块分两种情况: 1.导入外部的变量或函数等: import {firstName, lastName, ...
- 【原】AFNetworking源码阅读(三)
[原]AFNetworking源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇的话,主要是讲了如何通过构建一个request来生成一个data tas ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(81)-数据筛选(万能查询)
系列目录 前言 听标题的名字似乎是一个非常牛X复杂的功能,但是实际上它确实是非常复杂的,我们本节将演示如何实现对数据,进行组合查询(数据筛选) 我们都知道Excel中是如何筛选数据的.就像下面一样 他 ...
- 【绝对干货】仿微信QQ设置图形头像裁剪,让你的App从此炫起来~
最近在做毕业设计,想有一个功能和QQ一样可以裁剪头像并设置圆形头像,额,这是设计狮的一种潮流. 而纵观现在主流的APP,只要有用户系统这个功能,这个需求一般都是在(bu)劫(de)难(bu)逃(xue ...
- 由js apply与call方法想到的js数据类型(原始类型和引用类型)
原文地址:由js apply与call方法想到的js数据类型(原始类型和引用类型) js的call方法与apply方法的区别在于第二个参数的不同,他们都有2个参数,第一个为对象(即需要用对象a继承b, ...
- JavaScript实现DOM对象选择器
目的: 根据传入的选择器类型选出第一个符合的DOM对象. ①可以通过id获取DOM对象,例如 $("#adom"); ②可以通过tagName获取DOM对象,例如 $(" ...
- 浅谈java异常[Exception]
学习Java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:589809992 我们一起学Java! 一. 异常的定义 在<java编程思想 ...
- [转载]SQL语句中的日期计算
1. 本月的第一天SELECT DATEADD(mm, DATEDIFF(mm,0,getdate()), 0) 2. 本月的最后一天SELECT dateadd(ms,-3,DATEADD( ...
- 计算Div标签内Checkbox个数或已被disabled的个数
先看下面的html: 计算div内的checkbox个数:$('#divmod input[type="checkbox"]').length 计算div内checkbox被dis ...
- iOS开源项目周报1222
由OpenDigg 出品的iOS开源项目周报第二期来啦.我们的iOS开源周报集合了OpenDigg一周来新收录的优质的iOS开发方面的开源项目,方便iOS开发人员便捷的找到自己需要的项目工具等. io ...