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