今回、東京てら子の内容が『Error Handling&Security』っていう
お題だったんですが、その部分はちゃんと自分も勉強したく、
個人的に一人エアてら子(ひよこ)を開催してみました。
すいません嘘です。たまたま同じ日にやってたってだけですw
実際のてら子にはほど遠い内容なので自分のblogでなら発表してもいいよねってことで、ここに勉強キロク。
これ分かってないと、てら子何言ってるか分からんだろうと。
先週会社の先輩に言われたことで、
「セキュリティとかエラーとかっていうのは作り手側が気を配ってあげられる部分だよね。
最大限、作り手は細かい所まで気を配ってあげればいいと思うよ。」
というお言葉を頂き、本当にその通りだなと。
自分のエラー知識はIOErrorでtrace出しとくとかその程度で、
セキュリティに関してはそんな案件に関わってこなかったという理由で
あんまり意識してやってこなかった部分なんですが、
今回のいろいろなXSS脆弱性とか言われてるのを見て
やっぱり最低限知っておく必要はあるよねと。
買っててよかったPDFオライリー。泣
このあたりをやってみるお。
第13章 例外とエラー処理
第19章 FlashPlayerのセキュリティ制限
// まずはthrow でエラーを投げる(その時点で中断処理)
throwで例外を発生させられる。型は何でも投げられるけど、
AdobeはErrorクラスのインスタンスを推奨しているよ!
throw new Error(“エラーイベントだよ!”);
// try/catch/finally
tryにエラーを起こす可能性のある処理を書く。
catchにその起こったエラーが飛んでくる。ここで受け取る。エラーがなければ当然無視される。
finally エラーに関係なく最後に処理される。省略してもOK。後処理のクリーンアップコードとかを書く。
すいませんfinallyとか全く知りませんでした。使ってきませんでした。。
try{ // ここでの例外処理がthrowでcatchへと投げられる。 throw new Error("エラーイベントだよ!"); }catch(e:Error){ trace(e.message); // 例えばここでもう一回入力させるようなボックスを表示してあげれば親切だよね。ということか。 }finally{ // クリーンアップコード。tryに入ったら必ず実行されるって覚えておけばいいよね。 }
// Errorクラスを拡張した独自CustomErrorクラスを作成
var type1 = false; var type2 = false; var type3 = false; if(type1){ throw new CustomError(); // デフォルト文言のエラー }else if(type2){ throw new CustomError("エラーイベントの文言を変えたよ!"); }else if(type3){ throw new CustomError("自由に変えれるよ!"); } package{ public class CustomError extends Error{ public function CustomError(message:String="デフォルトエラー文言", id:*=0) { super(message, id); } } }
// エラーイベントが複数の場合、catchブロックを複数持つことができる。(!)
カスタムErrorクラスをその数用意しておけばcatchのErrorでエラー処理を分岐できる。
Error(“エラー文言”);のエラー文言でエラー処理分岐などをすると複雑になるにつれ
修正が難しくなるのでエラーの拡張クラスとして作成する。
この時catchブロックは特殊なエラー処理から一般的なエラー処理に向かって記述する。
Error -> CustomError1 で CustomError1 -> CustomError2,3 から作られてる時
catchでのエラー判別がスーパークラスでも反応してしまうため、例えば1つ目にCustomError1書くと
どのエラーでもそこで引っかかるというわけ。
// Errorクラスを拡張した独自CustomErrorクラスを作成 var CustomError1; // Errorクラスを拡張 var CustomError2; // CustomError1クラスを拡張 var CustomError3; // CustomError1クラスを拡張 try{ func(); // このメソッド内での3種類のエラーを振り分けたい }catch(e:CustomError3){ trace(e.message); // エラー回復処理その3 }catch(e:CustomError2){ trace(e.message); // エラー回復処理その2 }catch(e:CustomError1){ trace(e.message); // エラー回復処理その1 }catch(e:Error){ trace(e.message); // 最後に想定していなかったエラーを捕まえる }
// AS3ではthrowで投げられたError処理のため、catchブロックを探して上位のコールスタック(呼出し元)を順に探す
public class Class3{ public function func(){ throw new Error("ここで問題発生"); } } public class Class2{ public function Class2(){ var problem:Class3 = new Class3(); problem.func(); // ここにはtryブロックがない。もう一つ上のコールスタックへ。 } } public class Class1{ public function Class1(){ try{ // データ型Errorを持つtry/catchブロックを見つけた。 var problem:Class2 = new Class2(); }catch(e:Error){ // ここでErrorをキャッチ trace(e.message); } } }
// そもそもfinallyはなぜ必要なのか??
public function sample(){ try{ throw new Error("テストエラー1"); }finally{ clear(); // クリーンアップ関数 } } try{ sample(); }catch(e:Error){ trace(e.message); }
だったらこれでErrorを呼び出し元にバブリングできるんじゃね?という疑問。
public function sample(){ throw new Error("テストエラー1"); clear(); } try{ sample(); }catch(e:Error){ // エラーがcatchブロックにキャッチされてしまうのでclear()に入らない。 trace(e.message); }
しかしErrorが投げられた時点で上の階層のcatchブロックへ処理が移るためclear()が実行されなくなる。なるほど。
// finallyブロックとバブリングでのエラー処理の順番
public function sample2():void { try { throw new Error(" テストエラー1"); // catchブロックがみつからないので1つ上のcatchに行く。 }finally{ try { throw new Error(" テストエラー2"); // 1つ目のエラーが処理される前にfinallyが処理される。 } catch (e:Error) { trace(" 内部でのキャッチ: " + e.message); } } } // 前述のメソッドを呼び出す、ほかの場所にある別のメソッドの中 try { sample2(); }catch(e:Error){ trace(" 外部でのキャッチ: " + e.message); } // 出力(内側の例外が最初にキャッチされる!) // 内部でのキャッチ: テストエラー2 // 外部でのキャッチ: テストエラー1
// returnを使ってtry/catch/finallyの制御フローを変更する。
下記のようにtry内で即returnしてもfinallyは通る。
でもこのメソッド自体はreturnでキャンセルされてるので最後のtraceまでは行かない。
try { return; throw new Error(" テストエラー"); } catch (e:Error) { trace(" キャッチされた: " + e.message); } finally { trace("finally が実行された"); } trace("ここのtraceまで来ない");
ちなみにreturnが”テストエラー”の後だったらその時点でError処理に入り、
return処理は実行されないまま以下となる。
// 出力 // キャッチされた: テストエラー // finally が実行された // ここのtraceまで来ない
次にcatch内にreturnの場合
この場合、エラーが起きた時点でそのメソッドを中断する時などに使える。
try { throw new Error(" テストエラー"); } catch (e:Error) { trace(" キャッチされた: " + e.message); return; } finally { trace("finally が実行された"); } trace("ここのtraceまで来ない"); // 出力 // キャッチされた: テストエラー // finally が実行された
// ビルトインエラーの処理
Soketクラスを使用した接続時にはセキュリティ制限によって失敗する場合がある。
その時、SecurityErrorが帰る。
var socket:Socket = new Socket(); try { // 指定されたポートへの接続の試み socket.connect("example.com", userPort); } catch (e:SecurityError) { // ユーザーにメッセージを表示するコード }
// こっちはIOErrorEventの場合
これはよく使うので省略。むしろエラー処理これくらいしか使ってなかった。。
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, function(e:IEErrorEvent){ trace(" ファイルの読み込みエラー"); });
というわけで、やっぱり自分の興味でやってきた楽しいコードとは違って、
覚えないといけないところなのですげー初歩的な部分からですが。。
でもこれもやり始めると楽しいということが分かったw
エラーで1日終わってセキュリティまで全然行けなかったので次回はセキュリティ行ってみる。
エアーてら子っていうより、
一人でてら子の内容のすごく基礎の部分をオライリー使って
そのまま勉強してみるっていうだけだったw
G.Wは勉強し放題!(`・ω・´)
you
あ、オライリーのPDF本。これ読む方が100倍いいっすよ。
詳説 ActionScript 3.0
つか技術書のPDFめちゃくちゃ便利だ。。今まで重いあれは何だったんだ。。(´・ω・`)