Frage

Wenn ich Jinja2 in Google App Engine renne, erhalte ich nutzlos Debug-Informationen. Ich nehme an, weil dieser Artikel in der FAQ ist:

  

My Tracebacks seltsam aussehen. Was ist los?

     

Wenn das speedups Modul nicht kompiliert wird, und Sie werden mit einer Python-Installation ohne ctypes (Python 2.4 ohne ctypes, Jython oder Googles App Engine) Jinja2 ist nicht in der Lage richtig Debug-Informationen zur Verfügung zu stellen und die Rückverfolgung kann unvollständig sein. Es gibt derzeit keine gute Abhilfe für Jython oder die App Engine als ctypes ist nicht verfügbar, da und es ist nicht möglich, die speedups Erweiterung zu verwenden.

Zwar gibt es keine ‚gute‘ Abhilfe für diesen im Moment gibt es jeder zu umgehen, so dass die gedruckten Informationen, wenn Ausnahmen auftreten können hilfreicher gemacht werden?

Danke für das Lesen.

Brian

War es hilfreich?

Lösung

Sie können dies umgehen, indem _ctypes und gestalt auf die Entwicklung des Servers C-Modul hinzugefügt weiße Liste mit monkeypatching.

Um dies zu tun, setzen Sie den folgenden Ausschnitt an der Spitze Ihres 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']

Sie können auch diesen Trick verwenden, um andere C-Module zu ermöglichen, wenn Sie ähnlich haben nur lokale Modul benötigt. Zu beachten ist, dass diese Module noch nicht wirklich funktionieren, wenn Sie bereitstellen, so Lauffläche vorsichtig.

Ein SDK 1.6.3 mit python2.7 müssen Sie den obigen Code ändern:

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']

Ein SDK 1.8.6 für Python 2.7, versuchen Sie dies:

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']

Andere Tipps

Vielleicht nur PyCharm interaktiven Debugger und Schritt durch den Code verwenden:

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

Ich verwende den folgenden monkeypatch etwas mehr hilfreiche Informationen zu ermöglichen, wenn eine Ausnahme während Vorlage Rendering Jinja2 auftritt:

# 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

Dies wird etwas genauer Ausnahme Tracebacks in Ihre Fehlerprotokolle führen. Ich denke, es ist nicht in der Regel zeigt Ihnen genau, was schief gelaufen ist (aber wenn ich mich recht erinnere es tut manchmal), aber es wird die Ausnahme zumindest einengen auf die richtige Vorlage.

Warum das funktioniert, weiß ich nicht (oder kann mich nicht erinnern).

Als Beispiel habe ich einige Code nur hinzugefügt, die eine Ausnahme von einer meiner Vorlagen auslösen. Unter dem Entwicklungs-Server, ist es das, was der „normale“ Exception-Handler zeigt ich:

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

Aber die Ausnahme ist, nicht in der accounts/base.html Vorlage, es ist in accounts/edit_card.html. Dies ist der frustrierend Teil der Debug-Jinja2 Vorlage Ausnahmen auf App Engine: Die Quelle der Ausnahme ist fast immer falsch dargestellt. Nach meiner Erfahrung ist die Quelle in der Regel entweder als die Eltern-Vorlage oder als eine Vorlage Makro angegeben.

Mit Ausnahme Protokollierung monkeypatch installiert, die gleiche Ausnahme generiert diese Zurückverfolgungs in den Protokollen:

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

Es gibt noch eine Menge von fremden Informationen hier, aber das Zurückverfolgungs mindestens Punkten ich in der richtigen Richtung. Sie machen geltend, dass das Problem auf der Leitung 54 von accounts/edit_card.html ist (die richtige Vorlage), aber die tatsächliche Ausnahme tritt bei der Linie 86.

Aber angesichts die richtige Vorlage und die richtige Ausnahme, ich kann ziemlich leicht feststellen, dass der lästige Code ist dies

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

, wo es keine sequence Variable im Template-Kontext.

Dies ist keine perfekte Lösung, aber ich habe es mächtig hilfreich.

Nicht sicher, ob das hilfreich sein, aber es könnte möglich sein, zumindest Add Block TemplateTag wie django ‚debug‘ ist, die zumindest helfen, das Problem zu lokalisieren.

Ein Weg, um zu vermeiden Affe-Patchen (die auf die sich verändernden Interna des SDK abhängt) ist das imp Modul zu verwenden, die zur Zeit zumindest nicht in der lokalen Entwicklungsumgebung deaktiviert. Dann nur Last _ctypes wie dies zu ermöglichen, besser Jinja2 Debuggen:

import imp
file, pathname, description =  imp.find_module('_ctypes')
imp.load_module('_ctypes', file, pathname, description)

Wenn ich ein Problem wie getroffen, dass ich versuche, es auf meinem lokalen ipython Shell zu debuggen. Ich frage mich, was der Code, den ein solcher Fehler erzeugt ist. Es soll ein Weg sein, einen Test für ihn zu schreiben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top