2

salesforce零基础学习(一百一十三)Trigger中获取IP地址的过程 - zero.zhang

 1 year ago
source link: https://www.cnblogs.com/zero-zyq/p/16255384.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

salesforce零基础学习(一百一十三)Trigger中获取IP地址的过程 - zero.zhang - 博客园

本篇参考:

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失效,只能运行时是同步的场景才可以,所以我们将代码进行提前。

910966-20220510213848165-849671487.png

新的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);
}

运行一下效果:

910966-20220510214627816-567186192.png

本来以为万事大吉了,可以正常使用了,结果case表还可以通过 web-to-case来创建,而本质上就是通过 org id & user id等信息加上case信息来嵌入的创建一个case数据,所以当 web-to-case场景,出现了如下的错误:System.UnexpectedException: Current session unavailable (System Code)

更重要的一点: 此种报错,即使添加 try catch也无法捕获,在code程度,想要handle不可能。

910966-20220510214858312-286460570.png

此种问题如果出现了,没有完美的规避方式。workaround solution可以简单参考以下两种:

1. 从业务上来获取数据规律,基于数据规避。我这次好在实际项目中的业务数据具有一定的规律,其他的途径创建的不会有这种类型数据,所以基于业务层面,增加了一些数据层面filter,只有满足情况下才通过 sessionManagement获取。

2. 可以考虑运行文情况。我们之前在salesforce零基础学习(一百零一)如何了解你的代码得运行上下文, web-to-case上下文是 SYNCHRONOUS,我们如果针对这个 callout只是rest场景下或者其他的场景的上下文才会运行,其他的不需要运行,也可以进行规避考虑。

总结:也算是第一次发现基于程序上无法try catch到的场景,但是毕竟也算是小概率事件,所以发现了以后找到相关解决方案即可。本身难度不大,mark一下。篇中有错误地方欢迎指出,有不懂欢迎留言。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK