28

Google App EngineでJinja2を実行していると、役に立たないデバッグ情報が表示されます。私はこれを収集しますこれはFAQのこの項目のためです:

私のトレースバックは奇妙に見えます。何が起こっていますか?

スピードアップモジュールがコンパイルされておらず、ctypesなしのPythonインストール(ctypesなしのPython 2.4、Jython、またはGoogleのAppEngine)を使用している場合、Jinja2は正しいデバッグ情報を提供できず、トレースバックが不完全である可能性があります。現在、JythonまたはAppEngineではctypesが利用できず、スピードアップ拡張機能を使用できないため、適切な回避策はありません。

現時点では、これに対する「適切な」回避策はありませんが、例外が発生したときに出力される情報をより役立つようにするための回避策はありますか?

読んでくれてありがとう。

ブライアン

4

6 に答える 6

29

これを回避するには、モンキーパッチを使用して_ctypesとgestaltを開発サーバーのCモジュールホワイトリストに追加します。

これを行うには、main.pyの上部に次のスニペットを配置します。

import os
if os.environ.get('SERVER_SOFTWARE', '').startswith('Dev'):
    # Enable ctypes for Jinja debugging
    from google.appengine.tools.dev_appserver import HardenedModulesHook
    HardenedModulesHook._WHITE_LIST_C_MODULES += ['_ctypes', 'gestalt']

同様のローカルのみのモジュールが必要な場合は、このトリックを使用して他のCモジュールを有効にすることもできます。これらのモジュールは、一度展開すると実際には機能しないことに注意してください。慎重に踏み込んでください。

python2.7を使用するSDK1.6.3では、上記のコードを次のように変更する必要があります。

import os
if os.environ.get('SERVER_SOFTWARE', '').startswith('Dev'):
    # Enable ctypes for Jinja debugging
    import sys
    from google.appengine.tools.dev_appserver import HardenedModulesHook
    assert isinstance(sys.meta_path[0], HardenedModulesHook)
    sys.meta_path[0]._white_list_c_modules += ['_ctypes', 'gestalt']

python2.7用のSDK1.8.6では、次のことを試してください。

PRODUCTION_MODE = not os.environ.get(
    'SERVER_SOFTWARE', 'Development').startswith('Development')
if not PRODUCTION_MODE:
    from google.appengine.tools.devappserver2.python import sandbox
    sandbox._WHITE_LIST_C_MODULES += ['_ctypes', 'gestalt']
于 2010-09-12T10:02:47.157 に答える
2

おそらく、PyCharmのインタラクティブデバッガーを使用して、コードをステップスルーするだけです。

http://www.jetbrains.com/pycharm/quickstart/#RunAndDebug

于 2010-08-05T21:55:08.327 に答える
2

次のモンキーパッチを使用して、Jinja2テンプレートのレンダリング中に例外が発生したときに少し役立つ情報を有効にします。

# Enabling this monkeypatch can help track down hard to find errors that crop
# up during template rendering (since Jinja's own error reporting is so
# unhelpful on AppEngine).
real_handle_exception = environment.handle_exception
def handle_exception(self, *args, **kwargs):
    import logging, traceback
    logging.error('Template exception:\n%s', traceback.format_exc())
    real_handle_exception(self, *args, **kwargs)
environment.handle_exception = handle_exception

これにより、エラーログにわずかに正確な例外トレースバックが記録されます。通常、何がうまくいかなかったのかを正確に示すとは思いませんが(ただし、正しく覚えていれば、時々そうなることがあります)、少なくとも例外を正しいテンプレートに絞り込むことができます。

なぜこれが機能するのか、私にはわかりません(または思い出せません)。

例として、テンプレートの1つに例外をトリガーするコードを追加しました。開発サーバーでは、これが「通常の」例外ハンドラーに表示されるものです。

Traceback (most recent call last):
  File "/Users/will/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/__init__.py", line 511, in __call__
    handler.get(*groups)
  File "/Users/will/workspace/keypremium/ki/shared/decorators.py", line 27, in inner
    return func(self, *args, **kwargs)
  File "/Users/will/workspace/keypremium/account/views.py", line 114, in get
    self.render_jinja('accounts/edit_card.html', ctx)
  File "/Users/will/workspace/keypremium/ki/webapp/handlers.py", line 186, in render_jinja
    return self.response.out.write(jinja.render(template_path, new_context))
  File "/Users/will/workspace/keypremium/ki/shared/jinja/__init__.py", line 21, in render
    return template.render(context)
  File "/Users/will/workspace/keypremium/ki/ext/jinja2/environment.py", line 705, in render
    return self.environment.handle_exception(exc_info, True)
  File "/Users/will/workspace/keypremium/ki/shared/jinja/environment.py", line 24, in handle_exception
    real_handle_exception(self, *args, **kwargs)
  File "/Users/will/workspace/keypremium/templates/accounts/edit_card.html", line 1, in top-level template code
    {% extends 'accounts/base.html' %}
UndefinedError: 'sequence' is undefined

ただし、例外はaccounts/base.htmlテンプレートにはなく、にありaccounts/edit_card.htmlます。これは、App EngineでのJinja2テンプレート例外のデバッグで最も苛立たしい部分です。例外のソースは、ほとんどの場合、誤って伝えられます。私の経験では、ソースは通常、親テンプレートまたはテンプレートマクロとして報告されます。

例外ロギングmonkeypatchがインストールされている場合、同じ例外がログに次のトレースバックを生成します。

Traceback (most recent call last):
  File "/Users/will/workspace/keypremium/ki/ext/jinja2/environment.py", line 702, in render
    return concat(self.root_render_func(self.new_context(vars)))
  File "/Users/will/workspace/keypremium/templates/accounts/edit_card.html", line 11, in root
    <div class="errors">
  File "/Users/will/workspace/keypremium/templates/accounts/base.html", line 11, in root
    </html>
  File "/Users/will/workspace/keypremium/templates/accounts/edit_card.html", line 54, in block_content
    <td>{{ form.cvv2|safe }}</td>
  File "/Users/will/workspace/keypremium/ki/ext/jinja2/environment.py", line 352, in getattr
    return getattr(obj, attribute)
  File "/Users/will/workspace/keypremium/ki/ext/jinja2/runtime.py", line 445, in _fail_with_undefined_error
    raise self._undefined_exception(hint)
UndefinedError: 'sequence' is undefined

ここにはまだ多くの無関係な情報がありますが、このトレースバックは少なくとも私を正しい方向に向けています。問題はaccounts/edit_card.html(正しいテンプレート)の54行目にあると主張していますが、実際の例外は86行目で発生しています。

しかし、正しいテンプレートと正しい例外を考えると、厄介なコードがこれであることが非常に簡単にわかります

{% for x in sequence.sequence() %}
    {{ x.y }}
{% endfor %}

sequenceテンプレートコンテキストに変数がない場合。

これは完璧な解決策ではありませんが、非常に役立つことがわかりました。

于 2010-09-16T17:05:23.337 に答える
1

それが役立つかどうかはわかりませんが、少なくとも問題の特定に役立つdjangoの「デバッグ」のようなブロックテンプレートタグを追加することは可能かもしれません。

于 2010-07-23T10:00:47.270 に答える
1

モンキーパッチ(SDKの内部の変更に依存)を回避する方法は、impモジュールを使用することです。このモジュールは、少なくとも現在、ローカル開発環境では無効にされていません。_ctypes次に、このようにロードして、Jinja2のデバッグを改善します。

import imp
file, pathname, description =  imp.find_module('_ctypes')
imp.load_module('_ctypes', file, pathname, description)
于 2015-02-02T14:50:42.847 に答える
0

このような問題が発生した場合は、ローカルのiPythonシェルでデバッグしようとします。そのようなバグを生成するコードは何でしょうか。そのためのテストを書く方法があるはずです。

于 2010-07-25T12:25:40.407 に答える