salesforce零基礎學習(一百一十三)Trigger中獲取IP地址的過程

zero.zhang發表於2022-05-12

本篇參考:

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一下。篇中有錯誤地方歡迎指出,有不懂歡迎留言。

相關文章