h5.core.interceptor.errorInterceptorについて

113 views
Skip to first unread message

hitomi kiguchi

unread,
Apr 19, 2013, 12:42:03 AM4/19/13
to hifive...@googlegroups.com
バグ報告・環境依存の問題の場合は、以下の項目をご記入ください。
 
--------------------------------------------------------------------
【hifiveのバージョン】1.1.3
【OS】CentOS 6
【ブラウザ(バージョン)】Firofox 20.0.1
--------------------------------------------------------------------
木口です。
よろしくお願い致します。

h5.core.interceptor.errorInterceptorが
何者かよく分からないので質問させてください。

errorInterceptorは、インターセプタでエラーが起こった場合にCall処理だと考えてよろしいでしょうか?

#APIでは「invocationから上がってきたエラーを受け取る」とあり、
#この「invocation」が指すのは「インターセプタに設定した処理(function)の繋ぎ情報(引数、前メソッド名、後メソッド実行)」なのかなと。
#よって、インターセプタのエラーハンドリングに使用する物なのかと思いました。
参考:http://www.htmlhifive.com/conts/web/view/tutorial/step13-aop

簡単な使い方のサンプル等ありましたら
教えていただけないでしょうか?

simdy

unread,
Apr 19, 2013, 3:46:18 AM4/19/13
to hifive...@googlegroups.com
しもだです。
 
errorInterceptorは、コントローラやロジック内で例外がスローされたときに
その例外オブジェクトを引数にしてcommonFailHandlerを呼ぶ、というものです。
(APIDocがきちんとしておらずすみません。修正します。)
 
commonFailHandlerは通常非同期処理(Deferred)の失敗時に
failハンドラをセットしていない時に呼ばれるものですが、
これを同期処理の例外発生にまで(意味的に)拡張します。
 
また、logInterceptorというものもあります(errorInterceptorと同じ名前空間にあります)。
メソッドの実行ログ・実行時間をログ出力することができます。
# ControllerおよびLogicが対象です。
主にデバッグ時の利用を想定しています。
 
(パフォーマンス計測などはブラウザ内蔵のツールでも取得できます。
内蔵のツールは高精度かつ詳細なデータがとれる点で利用価値が高いものですが、
すべてを計測してしまうため、計測の粒度・対象の調整がしづらい面があります。
そのため、デバッグ時に頻繁に必要になると思われるメソッドトレーサについて
FWがデフォルトで内蔵しています。)
 

2013年4月19日金曜日 13時42分03秒 UTC+9 hitomi kiguchi:

hitomi kiguchi

unread,
Apr 26, 2013, 3:46:21 AM4/26/13
to hifive...@googlegroups.com
木口です。
解答ありがとうございます。

>errorInterceptorは、コントローラやロジック内で例外がスローされたときに
>その例外オブジェクトを引数にしてcommonFailHandlerを呼ぶ、というものです。

なるほど。勘違いしておりました。
コントローラやロジックの例外throwをトリガーに動くエラーハンドラなのですね。

ちなみに、errorInterceptor をコントローラやロジックに設定するにはどう書けばよういでしょうか?
#AOPを適用するで出てくるインターセプタとerrorInterceptorは関係があるのでしょうか?

2013年4月19日金曜日 16時46分18秒 UTC+9 simdy:

simdy

unread,
May 9, 2013, 1:31:11 AM5/9/13
to hifive...@googlegroups.com
しもだです。
 
>#AOPを適用するで出てくるインターセプタとerrorInterceptorは関係があるのでしょうか
 
errorInterceptorは、logInterceptor等と同じくインターセプタそのもの(インターセプタの一つ)です。
ですので、
にしたがって設定することで利用可能になります。
 
例えば、以下のようなコードでアスペクトを設定した場合、
任意のコントローラまたはロジックのメソッドでthrow new Error(); すると
その例外がキャッチされcommonFailHandlerに処理が移ります
(スローされた例外オブジェクトはcommonFailHandlerの引数として渡されます)。
 
(function(){
 $
(document).bind('h5preinit', function(){
  h5
.settings.commonFailHandler = function(errorThrown){
   console
.log(errorThrown);
 
};
 
var errorAspect = {
   interceptors
: h5.core.interceptor.errorInterceptor
 
};
  h5
.settings.aspects = errorAspect;
 
});
})();

 
 
なお、上記コードは「jQueryの読み込み」と「hifiveの読み込み」の間に記述してください。
 

2013年4月26日金曜日 16時46分21秒 UTC+9 hitomi kiguchi:

hitomi kiguchi

unread,
May 9, 2013, 6:34:01 AM5/9/13
to hifive...@googlegroups.com
木口です。
解答ありがとうございます。

うまく行きませんでした。。

現在、Logicのfailハンドラ内でリトライ処理を実装しており、
指定回数リトライに失敗した場合は例外をthrowしています。
#このthrowした例外をerrorInterceptorで捕まえてcommonFailHandlerへ渡したいのです・・
#こんな感じです。
 hogeLogicのfailハンドラ内で例外をthrow
 →errorInterseptorがcommonFailHandlerを実行
 →commonFailHandlerが共通エラー画面を表示
 現在は「uncaught exception: [object Object]」とコンソールに出ている状況です。

ひょっとして、errorInterceptorからcommonFailHandlerを呼ぶ場合でも
Deferredのfailハンドラを設定している場合はcommonFailHandlerは呼ばれないのでしょうか?

2013年5月9日木曜日 14時31分11秒 UTC+9 simdy:

simdy

unread,
May 9, 2013, 6:46:43 AM5/9/13
to hifive...@googlegroups.com
しもだです。
 
(残念ながら)その例外スローをerrorInterceptorで捕捉することはできません。
なぜなら、そのfailハンドラは"非同期"で呼ばれている
=try節の中をすでに出てしまっているのでcatchできないから、です。
# この辺が、非同期処理(Deferred)と例外の相性がイマイチなところです…
 
上記のような理由なので、
>errorInterceptorからcommonFailHandlerを呼ぶ場合でも
>Deferredのfailハンドラを設定している場合はcommonFailHandlerは呼ばれない
というわけではありません(念のため)。
 
なお、伺った内容からすると、
>指定回数リトライに失敗した場合は例外をthrow
ではなく、そのロジック(のメソッド自身)がPromiseを返しているべきと思います。
(そのメソッドの処理は非同期だから。)
で、そうしておけば、そのロジックの利用者が
failハンドラを設定しなければcommonFailHandlerが呼ばれるので
意図(?)した動作を実現できると思います。
 

2013年5月9日木曜日 19時34分01秒 UTC+9 hitomi kiguchi:

木口です。
解答ありがとうございます。

hitomi kiguchi

unread,
May 15, 2013, 3:37:46 AM5/15/13
to hifive...@googlegroups.com
木口です。


>(残念ながら)その例外スローをerrorInterceptorで捕捉することはできません。
>なぜなら、そのfailハンドラは"非同期"で呼ばれている
>=try節の中をすでに出てしまっているのでcatchできないから、です。

コールバックからthrowした例外は受け取ることができないのですね。
勉強不足でした。
#非同期の例外処理の基本なのですね。。

>>errorInterceptorからcommonFailHandlerを呼ぶ場合でも
>>Deferredのfailハンドラを設定している場合はcommonFailHandlerは呼ばれない
>というわけではありません(念のため)。

確認しました。


>ではなく、そのロジック(のメソッド自身)がPromiseを返しているべきと思います。
>(そのメソッドの処理は非同期だから。)
>で、そうしておけば、そのロジックの利用者が
>failハンドラを設定しなければcommonFailHandlerが呼ばれるので
>意図(?)した動作を実現できると思います。

failハンドラを登録して かつ commonFailHandlerを用意しているのですが、
commonFailHandlerが実行されます。
#failハンドラを登録している場合はcommonFailHandlerは実行されないという理解なのですが。。

下記を実行すると、
alert
("Error!!"); → 
alert("fail!! "+ errObj.status); の順で実行されます。

h5preinit.js
 $(document).bind('h5preinit', function(){
 
     h5
.settings.commonFailHandler = function(obj){
      alert
("Error!!");
      console
.log(obj);
 
};
 
 
var aspect = {
   interceptors
: [h5.core.interceptor.errorInterceptor, h5.core.interceptor.logInterceptor],
 
};
  h5
.settings.aspects = [aspect];
 
});

コントローラとロジック
$(function () {
   
function ShowTableDataLogic() {};

   
ShowTableDataLogic.prototype = {
        __name
: 'showTableDataLogic',

       
get: function(tableName) {
           
var dfd = this.deferred();
           
var retryCnt = 1;
       
            dfd
.notify();
           
this._getDef(tableName, retryCnt, dfd);
           
return dfd;
       
},

        _getDef
: function(tableName, retryCnt, dfd) {
               
           
this._get(tableName, retryCnt, dfd).done(function(data) {
                dfd
.resolve(data);
           
}).fail(function (errObj) {
                alert
("fail!! "+ errObj.status); 
            });

           
return dfd;
       
},
       
        _get
: function(tableName) {
           
var def = h5.ajax({  
                type
: 'GET',
                data
: {tableName: tableName},
                dataType
: 'json',
                url
: 'show-table-dataa',
                timeout
: 3000,
           
});
           
return def.promise();
       
}
   
};
   
   
var onChangeController = {
               
        __name
: 'onChangeController',
        __templates
: 'rowsAreaTemp.ejs',
        showTableDataLogic
: new ShowTableDataLogic(),
       
       
'#tableSelector change': function (tableName){
           
var tableName = this.$find('#tableSelector option:selected').val();
           
if(tableName == -1) return null;
           
           
this.showTableDataLogic.get(tableName).done(this.own(function(data){
               
this.view.update(・・・・);
           
}));
       
}
   
};
    h5
.core.controller('#menueDiv', onChangeController);
});



2013年5月9日木曜日 19時46分43秒 UTC+9 simdy:

simdy

unread,
May 15, 2013, 5:56:41 AM5/15/13
to hifive...@googlegroups.com
しもだです。
 
>failハンドラを登録して かつ commonFailHandlerを用意しているのですが、
>commonFailHandlerが実行されます。
>#failハンドラを登録している場合はcommonFailHandlerは実行されないという理解なのですが。。
こちらの件、検証の結果バグであることがわかりましたので、対応いたします。
 
h5.ajax()は($.ajax()と同様)「jqXHRオブジェクト(を少し加工したもの)」を返すのですが、
このオブジェクトのpromise()メソッドで返されるプロミスオブジェクトにおいて
commonFailHandlerへの対応が抜けていました。
 
いただいたコードでは_get()にて reutrn def.promise() としていたため、
failハンドラを登録しているにも関わらずcommonFailHandlerが呼ばれていました。
(ちなみに、ここをreturn def; とすると、commonFailHandlerは呼ばれなくなります。)
 

2013年5月15日水曜日 16時37分46秒 UTC+9 hitomi kiguchi:

hitomi kiguchi

unread,
May 16, 2013, 2:09:37 AM5/16/13
to hifive...@googlegroups.com
木口です。

>こちらの件、検証の結果バグであることがわかりましたので、対応いたします。
>Issue登録済:https://github.com/hifive/hifivemain/issues/202

了解しました。

>(ちなみに、ここをreturn def; とすると、commonFailHandlerは呼ばれなくなります。)

動作確認しました。

2013年5月15日水曜日 18時56分41秒 UTC+9 simdy:
Reply all
Reply to author
Forward
0 new messages