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 ...
随机推荐
- 【翻译】MongoDB指南/聚合——聚合管道
[原文地址]https://docs.mongodb.com/manual/ 聚合 聚合操作处理数据记录并返回计算后的结果.聚合操作将多个文档分组,并能对已分组的数据执行一系列操作而返回单一结果.Mo ...
- Android学习探索之Java 8 在Android 开发中的应用
前言: Java 8推出已经将近2年多了,引入很多革命性变化,加入了函数式编程的特征,使基于行为的编程成为可能,同时减化了各种设计模式的实现方式,是Java有史以来最重要的更新.但是Android上, ...
- jQuery.template.js 简单使用
之前看了一篇文章<我们为什么要尝试前后端分离>,深有同感,并有了下面的评论: 我最近也和前端同事在讨论这个问题,比如有时候前端写好页面给后端了,然后后端把这些页面拆分成很多的 views, ...
- Axure 8.0.0.3312可用注册码
用户名:aaa 注册码:2GQrt5XHYY7SBK/4b22Gm4Dh8alaR0/0k3gEN5h7FkVPIn8oG3uphlOeytIajxGU 用户名:axureuser 序列号:8wFfI ...
- C# 实时折线图,波形图
此Demo是采用VS自带的Chart图表控件,制作实时动态显示的折线图,和波形图. 涉及到知识如下: Chart 控件,功能强大,可以绘制柱状图,折线图,波形图,饼状图,大大简化了对图的开发与定制. ...
- RSA算法
RSA.h #ifndef _RSA_H #define _RSA_H #include<stdio.h> #include<iostream> #include<mat ...
- Android 在Android代码中执行命令行
1.路径最好不要是自己拼写的路径/mnt/shell/emulated/0/wifidog.conf 最好是通过方法获取的路径,不然可能导致命令无效 (挂载点的原因) public static f ...
- git远程库GitHub
首先,注册一个GitHub(github.com)帐号,免费获得Git远程仓库 由于本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以,需要一点设置: 第1步:创建SSH Key.在用 ...
- How to accept Track changes in Microsoft Word 2010?
"Track changes" is wonderful and remarkable tool of Microsoft Word 2010. The feature allow ...
- CYQ.Data V5 从入门到放弃ORM系列:教程 - Log、SysLogs两个日志类使用
Log 静态类介绍: Public Static (Shared) Methods GetExceptionMessage 获取异常的内部信息 WriteLogToDB Overloaded. 将日志 ...