FlaskをJSから叩いてエラーになった時に対話的デバッグする方法
WebアプリフレームワークのFlask(が内部で使っているWerkzeug)は、デバッグモードをONにしておくとエラーが起きた時にそのエラー画面からブラウザ上で対話的にコードを実行したり変数を表示させたりしてデバッグが出来る。これは超便利。なのだけど、最近JSからAPIを叩くケースが多くなって、その場合JSが予期しないHTMLを受け取ってパースに失敗するだけなので折角の対話的デバッグが生かせない。
そこで、エラー時には新しいwindowを開いて、レスポンスの内容をそちらに書き出すようにした。初回だけポップアップブロックが発動してしまうけど、それ以降はこれでAPIでも対話的デバッグが出来る。
$.ajax({ url:'/buggy/', data: 'q=42', success: function(x){console.log(x)}, error:function(x){ var w = window.open('', 'debug_stuff', 'width=540,height=150'); w.document.open(); w.document.write(x.responseText); w.document.close(); } });
サーバ上でpdbデバッグという案(thanks @cocoatomo)に関しては、サーバのコード中でpdb.set_trace()で止めた場合は、コンソール上で対話的にデバッグすることはできるのですけど、python -mpdb server.pyした場合、例外発生時期待通りに対話的デバッガに入らない。おそらくFlask自体の例外処理と干渉してる。
「スタックトレースを生かしたまま持っておいて、デバッグ用の画面にリダイレクトしているだけなので、リダイレクトのURLを適当に拾ってブラウザからそのURLにアクセスすればデバッグ画面を開けます。」(thanks @methane) がとても参考になったけども、どうも僕の環境ではリダイレクトはしていないみたいに見えて、あとXMLHttpRequestがリダイレクト先に勝手にアクセスするので面倒くさい。
このアドバイスがヒントになって、最終的にはここに書かれている内容に辿り着いた:
debugging - Posting JSON and python Flask - any techniques to use the Werkzeug debugger? - Stack Overflow