Visualforceを開発した際のExceptionエラー発生時の対応について考えてみました。
通常Exceptionエラーが発生した際には次のような画面が表示されます。
このエラーはID型に文字列をセットしようとして発生しています。
コードはこんな感じ。
public with sharing class ExceptionMessegeController { public ExceptionMessegeController() { Id exceptionId = 'error'; } }
単純な処理の場合はどこでエラーが発生したのかすぐに見つかりますが、複雑になってくるとこれだけでは探すのが大変になってきます。デバックログなどで探す方法もありますが、本番環境などでアクセスできないケースもあるかなと思います。
そういうことからもっと詳細なエラー情報をメッセージとして表示してみようと下記のようにExceptionメッセージを表示するメソッドを作ってみました。
/* * 異常系メッセージ表示 * @param : Exception [e] * @return : なし */ public static void msgError(Exception e) { // エラーメッセージを表示 ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'システムエラーが発生しました。')); // Exceptionメッセージを表示 ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,e.getMessage())); // エラー発生原因を表示 ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Line:' + String.valueOf(e.getLineNumber()) + '【' + e.getTypeName() + '】')); }
次の処理でExceptionメッセージ、エラー発生行、Excetionの種別を取得できます。
- e.getMessage()
- e.getLineNumber()
- e.getTypeName()
これをCommonUtil等の共通クラスに用意し、try-catchのcatch処理で呼び出します。
コードは次のようになります。
public with sharing class ExceptionMessegeController { public ExceptionMessegeController() { try { Id exceptionId = 'error'; } catch (Exception e) { CommonUtil.msgError(e); return; } } }
これでExcetionエラー発生時に詳細な情報をメッセージで表示できます。
表示されるメッセージは次のようになります。
行番号やExceptionの種別も一目でわかるので、本番環境にアクセスできなくてもSandbox環境で大体のエラー発生箇所を確認できます。エラー発生時にこんな画面が表示されたと画面キャプチャが届いた時もエラー発生箇所が確認しやすくなるかなと思います。
DaoクラスやActionクラスなどに処理を分ける場合も、呼び出し元のクラスだけにtry-catchがあれば大丈夫です。
例えば次のようなDaoクラスをControllerクラスから呼び出します。
public with sharing class ExceptionMessegeDao { public User getUser() { return [ select Id from User where Id =: UserInfo.getUserId() and IsActive = false ]; } }
このDaoクラスではログインユーザのIDと一致し、無効になっているユーザを取得するという取得不可条件でユーザ取得クエリを実行しています。
呼び出し元のController側はこんな感じ。
public with sharing class ExceptionMessegeController { // Daoクラス private ExceptionMessegeDao dao; public ExceptionMessegeController() { // Daoクラス this.dao = new ExceptionMessegeDao(); try { // Daoクラスからユーザ情報取得 User objUser = this.dao.getUser(); } catch (Exception e) { CommonUtil.msgError(e); return; } } }
これを実行すると次のようにエラーメッセージが表示されます。
エラー内容としては次のとおり
①List has no rows for assignment to SObject
クエリ取得件数が0件
②Line:4【System.QueryException】
4行目でSystem.QueryExceptionが発生
※ここでの4行目というのはDaoクラス側の行番号となりました。
どこのクラスで発生しているかまで確認したい場合は、「e.getStackTraceString()」を使用すると確認できます。
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, e.getStackTraceString()));
Exceptionエラー発生時にはこんな感じでメッセージが表示されると対応しやすくなるかと思います。開発中でも予期せぬエラーが発生した際にこんなケースもあったんだと気づきやすいです。