本篇参考:
https://developer.salesforce.com/docs/atlas.en-us.228.0.apexcode.meta/apexcode/apex_class_Auth_SessionManagement.htm
https://help.salesforce.com/s/articleView?language=en_US&type=1&id=000339386
机缘巧合下碰到了这种问题,还挺好玩,记录一下,方便以后再次遇见情况下快速解决。背景如下:
在某个表的创建或者修改的场景下,满足指定条件下会对外部进行一个CALLOUT操作,然后将结果进行相关的更新,接口要求传递当前运行上下文的用户的IP address。demo就先以Case为例。
声明一个trigger,新的表的trigger还好,但是我们可能实际做的是一个二期,维护或者长期的项目,可能有很多handler来执行,这里简单模拟。
trigger CaseTrigger on Case(after insert, after update) { //DO something, like future callout CaseHandler.executeCaseHandler(); }
CaseHandler
public with sharing class CaseHandler { @future public static void executeCaseHandler() { String ipAddress; Map<String, String> session = Auth.SessionManagement.getCurrentSession(); ipAddress = session.get('SourceIp'); System.debug(LoggingLevel.INFO, '*** ipAddress: ' + ipAddress); } }
这样写完运行会报错: Current session unavailable,如果运行在future这种异步的,获取session失效,只能运行时是同步的场景才可以,所以我们将代码进行提前。
新的CaseHandler
public with sharing class CaseHandler { @future public static void executeCaseHandler(String ipAddress) { System.debug(LoggingLevel.INFO, '*** ipAddress: ' + ipAddress); } }
新的CaseTrigger
trigger CaseTrigger on Case(after insert, after update) { String ipAddress; if(!System.isFuture()) { Map<String, String> session = Auth.SessionManagement.getCurrentSession(); ipAddress = session.get('SourceIp'); } //DO something, like future callout CaseHandler.executeCaseHandler(ipAddress); }
运行一下效果:
本来以为万事大吉了,可以正常使用了,结果case表还可以通过 web-to-case来创建,而本质上就是通过 org id & user id等信息加上case信息来嵌入的创建一个case数据,所以当 web-to-case场景,出现了如下的错误:System.UnexpectedException: Current session unavailable (System Code)
更重要的一点: 此种报错,即使添加 try catch也无法捕获,在code程度,想要handle不可能。
此种问题如果出现了,没有完美的规避方式。workaround solution可以简单参考以下两种:
1. 从业务上来获取数据规律,基于数据规避。我这次好在实际项目中的业务数据具有一定的规律,其他的途径创建的不会有这种类型数据,所以基于业务层面,增加了一些数据层面filter,只有满足情况下才通过 sessionManagement获取。
2. 可以考虑运行文情况。我们之前在salesforce零基础学习(一百零一)如何了解你的代码得运行上下文, web-to-case上下文是 SYNCHRONOUS,我们如果针对这个 callout只是rest场景下或者其他的场景的上下文才会运行,其他的不需要运行,也可以进行规避考虑。
总结:也算是第一次发现基于程序上无法try catch到的场景,但是毕竟也算是小概率事件,所以发现了以后找到相关解决方案即可。本身难度不大,mark一下。篇中有错误地方欢迎指出,有不懂欢迎留言。