0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Salesforce 管理パッケージにおいてスタックトレースを扱いたかった。

Posted at

親知らずを抜きました。CLBです。
今回は Salesforce の Apex Rest API 開発でメッセージを正しくできなかった失敗と、
どうすれば正しく表示できるのかを調べたけど、ダメそうだった記録です。

ロギングの失敗:表示されないスタックトレース

業務では以下のようなシステムを作成していました。

  1. フロントエンド(FE)が画面を表示
  2. Salesforce に パッケージ化 したApexロジックを配置(これがいわゆるバックエンド、BEになります。)
  3. REST API で通信してロジックを実行。

スクリーンショット 2020-11-14 20.03.32.png

本当はちょっと違いがありますが、
どこにでもある一般的な Webアプリだと思っていただければ大丈夫です。

図に書いてある通り、例外エラーの時はスタックトレースが出るよう設定していました。
実際のコードとしては以下のような形で、

   @HttpPost
    global static String doPost() {
        String res;
        try {
            throw new TestException();
        } catch (Exception e) {
            res = e.getStackTraceString();
        }
        return res;
    }

このメソッドに対応するAPIをコールすると、


{
   "FOO.throwException: line 4, column 1 \n BAR.method: line 2, column 1"
}

のような形で表示される形です。
当然ながら開発者はパッケージ化していない状態で確認しているので、普通にスタックトレースを確認することができていました。
がいざ実際にパッケージ化したものをみて見ると

{
    "(名前空間)"
}

おおい!名前空間しか表示されていないやないかーい。

原因と解決の試み

https://help.salesforce.com/articleView?id=000319981&type=1&mode=1
に似たような内容が書いてあるのですが、

  • 管理パッケージのデバッグログが有効になっている場合、完全なスタックトレースが結果に表示されます。
  • スタックトレースの難読化や非表示はすべて、パートナーが独自実装の詳細を公開しないように保護するためのものです。
    という仕様があるようです。
    ただし、 管理パッケージのデバッグログ に関してはパッケージを作成した組織が
    インストールした組織に対してログインして設定を行う場合のみに有効らしい(どなたか詳しい人がいたら教えてください。)

でどうしたか?というと、
以下catch句でエラーログを適当なオブジェクトに保存してあげれば、ええんでね?と思ったがコレも上手く行かず。

    @HttpPost
    global static String doPost() {
        String res;
        try {
            throw new TestException();
        } catch (Exception e) {

            // カスタムオブジェクトに保存する
            // これも上手く行かない
            Error_Log__c customObj = new Error_Log__c(
                StackTrace__c = e.getStackTraceString()
            );
            insert customObj;
        }

        return res;
    }

開発者コンソールからオブジェクトに保存した内容を見ると・・・

StackTrace__c : "(名前空間)"

ううむ・・・厄介だ。

Sentry に送る?

https://github.com/jmather/SentryForSalesforce
非管理パッケージで発生した例外であれば、どうやら例外を保持できるらしいので
非管理パッケージに例外クラスをラップしておけばできるっぽいが、
ソースコードを一切合切公開しないと行けないので、それはそれで無理だよな・・・・

最後に

管理パッケージでトランザクションが開始された場合、情報を再発生させて登録ユーザに戻すのではなく、管理パッケージ内ですべての例外処理および解決策を実行する必要があります。
https://help.salesforce.com/articleView?id=000319981&type=1&mode=1

そんな事ができるなら苦労しないんだけどね・・・
まぁ我々にできる事と言えば、

try {
    throw new TestException();
} catch (Exception e) {
    return 'エラーです。value=' + val;
}

でしっかりとエラーログを書く事だけですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?