ちょっとニッチな要件かもしれませんが
ApexトリガでエラーのときにAPIコールしたい
※エラー自体は握りつぶさない
を実装したのでまとめます。
今年はアドベントカレンダーで2記事投稿します(*'ω'*)
今回もチャッピー(ChatGPT)にほぼ丸投げしました。
APIコールのネタは、1日目で書いたSlack通知を流用します!
下ごしらえ
Slack通知クラスにエラー通知のメソッドを追加しておきます。
public class SlackNotifier {
@future(callout=true)
public static void sendOpportunityTriggerErrorNotification() {
String message = '商談トリガーでエラーが発生しました!\n';
// Slack Incoming Webhook
String webhookUrl = 'https://hooks.slack.com/services/xxxx/yyyy/zzzz';
HttpRequest req = new HttpRequest();
req.setEndpoint(webhookUrl);
req.setMethod('POST');
req.setHeader('Content-Type', 'application/json');
// Slackに送るJSON
Map<String,Object> payload = new Map<String,Object>();
payload.put('text', message);
req.setBody(JSON.serialize(payload));
Http http = new Http();
http.send(req);
}
}
嘘つきチャッピーの提案
SalesforceのApexトリガについて質問です トリガでエラーが発生する際にAPIコールをしたいのですが、どのような方法で実装できますか?
→要約すると、Queueableで通知すりゃいいとのことでした。
てことで一応信じまして
エラー通知のQueueableクラスを用意して
public class ErrorNotificationJob implements Queueable, Database.AllowsCallouts {
public void execute(QueueableContext context) {
SlackNotifier.sendOpportunityTriggerErrorNotification();
}
}
商談トリガに
例外スロー+キュー作成+再スロー
を書きます
public class OpportunityTriggerHandler {
public class CustomException extends Exception {}
public static void afterInsert(List<Opportunity> newList) {
try{
List<Id> notifyIds = new List<Id>();
for (Opportunity opp : newList) {
// Insert 時点で Closed Won なら通知
if (opp.StageName == 'Closed Won') {
notifyIds.add(opp.Id);
}
}
if(true) {
throw new CustomException('test');
}
for (Id oppId : notifyIds) {
SlackNotifier.sendOpportunityWonNotification(oppId);
}
} catch (Exception e) {
// 非同期で API コールアウト
System.enqueueJob(new ErrorNotificationJob());
// 必要なら再スローして処理全体をロールバック
throw e;
}
}
}
商談レコード作成してエラーが起きたとき、、

→Slack通知はされない
ロールバックされるんだから、まあそうなるよね!
本命のプラットフォームイベントを使ってみる
方法1でさらっと嘘つかれたのですが、
方法2ではPlatform Eventsを使うと書いてありますので
こちらを試してみます。
エラーイベントのトリガでSlack通知を呼び出します
trigger ErrorEventTrigger on Error_Event__e (after insert) {
for (Error_Event__e eventRecord : Trigger.new) {
SlackNotifier.sendOpportunityTriggerErrorNotification();
}
}
商談トリガは
例外スロー+エラーイベント発行+再スロー
に直します
public class OpportunityTriggerHandler {
public class CustomException extends Exception {}
public static void afterInsert(List<Opportunity> newList) {
try{
List<Id> notifyIds = new List<Id>();
for (Opportunity opp : newList) {
// Insert 時点で Closed Won なら通知
if (opp.StageName == 'Closed Won') {
notifyIds.add(opp.Id);
}
}
if(true) {
throw new CustomException('test');
}
for (Id oppId : notifyIds) {
SlackNotifier.sendOpportunityWonNotification(oppId);
}
} catch (Exception e) {
// エラーイベントを発行
EventBus.publish(new Error_Event__e());
// 必要なら再スローして処理全体をロールバック
throw e;
}
}
}
商談レコード作成してエラーが起きたとき、、

→Slack通知されました!

プラットフォームイベント発行は
ロールバックに影響されないことがわかりました(*'ω'*)
今回は検証用に簡易な実装にしていますが
エラーイベントに項目作って、イベント発行時に情報を渡してあげれば
エラー通知の内容はもっと豪華になるかと思います。
チャッピーとの会話
実はこの会話は2回目、1回目はプラットフォームイベントを一番最初に提案してくれてました。
1回目はプラットフォームイベント発行のサンプルコードがコンパイルエラーになりました。
公開期限は2025年内で🎅
あとがき
先日プライベートPCを買い替えたので
業務でも使っていたCursorを開発環境にしました。
LLMはもちろんGPTです。日本語の理解力がほかのに比べていい気がします。
環境構築するとき、これまではネットで検索してこんな感じの記事を探してましたが、、
今はチャッピーが詳しく教えてくれるのだから良い時代です。
デフォルトだとサイドバーとかターミナルウィンドウ出ていないから
ガチ初心者にはすこし不親切かもと思いましたが
聞いたらそういうのも教えてくれるのでしょう。
この1年で生成AIが一気に生活でも業務でも身近になりました。
これからもっと使いこなせる人になりたいです。
そんな2025年の締めで終わります。
メリークリスマス、よいお年を!(^_-)-☆



