チェンジセット 1973

差分発生行の前後
無視リスト:
コミット日時:
2008/12/08 18:57:43 (3 年前)
コミッタ:
yossy
ログメッセージ:

Thread: デフォルトのエラーハンドラを登録可能に。defaultErrorHandler メソッドを登録すると、簡単にエラーを出力可能。

ファイル:

凡例:

変更無し
追加
削除
更新
コピー
移動
  • as3/Thread/trunk/src/org/libspark/thread/Thread.as

    r1972 r1973  
    135135                private static var _toplevelThreads:Array = []; 
    136136                private static var _uncaughtErrorHandler:Function = null; 
     137                private static var _defaultErrorHandlers:Dictionary = null; 
    137138                 
    138139                /** 
     
    236237                private static function getUncaughtErrorHandler():Function 
    237238                { 
    238                         return uncaughtErrorHandler || defaultUncaughtErrorHandler; 
     239                        return uncaughtErrorHandler || defaultErrorHandler; 
    239240                } 
    240241                 
    241242                /** 
    242243                 * 例外ハンドラのデフォルトの実装です. 
     244                 *  
     245                 * <p>このハンドラでは、例外の内容及び発生元の Thread の文字列表現を出力します。</p> 
    243246                 *  
    244247                 * @param       e       発生した例外 
    245248                 * @param       t       例外が発生したスレッド 
    246                  * @private 
    247                  */ 
    248                 private static function defaultUncaughtErrorHandler(e:Object, t:Thread):void 
     249                 */ 
     250                public static function defaultErrorHandler(e:Object, t:Thread):void 
    249251                { 
    250252                        trace((t ? t.toString() + ' ' : '') + (e is Error ? (e as Error).getStackTrace() : e.toString())); 
     253                         
     254                        if (currentThread != null) { 
     255                                next(null); 
     256                        } 
     257                } 
     258                 
     259                /** 
     260                 * 現在実行中のスレッドおよびその子スレッドで例外が発生した場合で、error メソッドによるハンドラの指定がなされていない場合にデフォルトで実行する実行関数を設定します. 
     261                 *  
     262                 * <p>ここで設定される実行関数は、発生した例外である Object と、例外が発生したスレッドである Thread のふたつの引数をとる関数である必要があります。</p> 
     263                 *  
     264                 * <p>この関数によって例外を処理できた (この関数内で再び例外が発生しなかった) 場合で、この関数内で 
     265                 * next メソッドによる実行関数の設定が行われなかった場合、例外が発生する前の実行関数の設定を復元します。</p> 
     266                 *  
     267                 * @param       klass   どの型の例外が発生した場合に関数を実行するかを示すクラス 
     268                 * @param       func    例外が発生した際に実行される実行関数 
     269                 */ 
     270                public static function registerDefaultErrorHandler(klass:Class, func:Function):void 
     271                { 
     272                        if (func != null) { 
     273                                addDefaultErrorHandler(klass, func); 
     274                        } 
     275                        else { 
     276                                removeDefaultErrorHandler(klass); 
     277                        } 
     278                } 
     279                 
     280                /** 
     281                 * デフォルトエラーハンドラマップを返します. 
     282                 *  
     283                 * @return      デフォルトエラーハンドラマップ 
     284                 * @private 
     285                 */ 
     286                private static function getDefaultErrorHandlers():Dictionary 
     287                { 
     288                        return _defaultErrorHandlers || (_defaultErrorHandlers = new Dictionary()); 
     289                } 
     290                 
     291                /** 
     292                 * デフォルトエラーハンドラをデフォルトエラーハンドラマップに追加します. 
     293                 *  
     294                 * @param       klass   エラークラス 
     295                 * @param       handler エラーハンドラ 
     296                 * @param       reset   リセットするか 
     297                 * @private 
     298                 */ 
     299                private static function addDefaultErrorHandler(klass:Class, handler:Function):void 
     300                { 
     301                        getDefaultErrorHandlers()[getQualifiedClassName(klass)] = new ErrorHandler(handler, false); 
     302                } 
     303                 
     304                /** 
     305                 * デフォルトエラーハンドラをデフォルトエラーハンドラマップから削除します. 
     306                 *  
     307                 * @param       klass   エラークラス 
     308                 * @private 
     309                 */ 
     310                private static function removeDefaultErrorHandler(klass:Class):void 
     311                { 
     312                        // ハンドラマップが存在しなければ何もしない 
     313                        if (_defaultErrorHandlers == null) { 
     314                                return; 
     315                        } 
     316                         
     317                        // ハンドラマップから削除 
     318                        delete _defaultErrorHandlers[getQualifiedClassName(klass)]; 
    251319                } 
    252320                 
     
    278346                                        } 
    279347                                        catch (e:Object) { 
    280                                                 defaultUncaughtErrorHandler(e, null); 
     348                                                defaultErrorHandler(e, null); 
    281349                                        } 
    282350                                        thread._error = null; 
     
    833901                 * 指定されたエラーに該当するエラーハンドラを返します. 
    834902                 *  
     903                 * <p>エラーハンドラが見つからず、デフォルトのエラーハンドラが登録されている場合、それを返します。</p> 
     904                 *  
    835905                 * @param       error   エラー 
    836906                 * @return      該当するエラーハンドラ。無ければ null 
     
    839909                private function getErrorHandler(error:Object):ErrorHandler 
    840910                { 
     911                        var handler:ErrorHandler = getErrorHandlerFrom(error, _errorHandlers); 
     912                        if (handler == null) { 
     913                                handler = getErrorHandlerFrom(error, _defaultErrorHandlers); 
     914                        } 
     915                        return handler; 
     916                } 
     917                 
     918                /** 
     919                 * 指定されたエラーに該当するエラーハンドラを指定されたハンドラマップから返します. 
     920                 *  
     921                 * @param       error   エラー 
     922                 * @param       handlers        ハンドラの検索先となるハンドラマップ 
     923                 * @return      該当するエラーハンドラ。無ければ null 
     924                 */ 
     925                private function getErrorHandlerFrom(error:Object, handlers:Dictionary):ErrorHandler 
     926                { 
    841927                        // ハンドラマップが存在しなければ null を返す 
    842                         if (_errorHandlers == null) { 
     928                        if (handlers == null) { 
    843929                                return null; 
    844930                        } 
     
    850936                        while (className != null) { 
    851937                                // ハンドラマップからクラス名をキーにしてハンドラを検索する 
    852                                 var handler:ErrorHandler = _errorHandlers[className]; 
     938                                var handler:ErrorHandler = handlers[className]; 
    853939                                // 見つかればそれを返す 
    854940                                if (handler != null) { 
  • as3/Thread/trunk/tests/org/libspark/thread/ExceptionTest.as

    r641 r1973  
    289289                        t.start(); 
    290290                } 
     291                 
     292                /** 
     293                 * デフォルトの例外ハンドラが設定されている場合に、それを実行することが出来るか。 
     294                 */ 
     295                test function defaultErrorHandler():void 
     296                { 
     297                        Static.log = ''; 
     298                         
     299                        var d:DefaultErrorHandlerTestThread = new DefaultErrorHandlerTestThread(); 
     300                        var t:TesterThread = new TesterThread(d, false); 
     301                        var e:Object; 
     302                        var th:Thread; 
     303                         
     304                        var handler:Function = function(ee:Object, tt:Thread):void 
     305                        { 
     306                                e = ee; 
     307                                th = tt; 
     308                                 
     309                                Thread.next(null); 
     310                        }; 
     311                         
     312                        Thread.registerDefaultErrorHandler(Error, handler); 
     313                         
     314                        t.addEventListener(Event.COMPLETE, async(function(ev:Event):void 
     315                        { 
     316                                Thread.registerDefaultErrorHandler(Error, null); 
     317                                 
     318                                assertSame(d.ex, e); 
     319                                assertSame(d, th); 
     320                        }, 1000)); 
     321                         
     322                        t.start(); 
     323                } 
    291324        } 
    292325} 
     
    884917        } 
    885918} 
     919 
     920class DefaultErrorHandlerTestThread extends Thread 
     921{ 
     922        public var ex:Error = new Error(); 
     923         
     924        override protected function run():void 
     925        { 
     926                throw ex; 
     927        } 
     928}