类型错误:“JsonObject”当应生成 pagenotfound 时,对象不可订阅
当发生内部 Pylons:python 错误时,我应该得到一个整洁的“找不到页面”页面,但我却得到了这个丑陋的“内部服务器错误”。
我在其他地方模拟了一个Python错误&生成正确的 pagenotfound 模板。在我的配置(development.ini)中:debug = false, full_stack = true ...以便在发生异常时呈现此页面。
这是 middleware.py 当前的样子:
"""Pylons middleware initialization"""
from beaker.middleware import CacheMiddleware, SessionMiddleware
from paste.cascade import Cascade
from paste.registry import RegistryManager
from paste.urlparser import StaticURLParser
from paste.deploy.converters import asbool
from pylons import config
from pylons.middleware import ErrorHandler, StatusCodeRedirect
from observer import Observer
from pylons.wsgiapp import PylonsApp
from routes.middleware import RoutesMiddleware
from r4l.lib.components.middleware.striptrailingslash import StripTrailingSlash
from r4l.config.environment import load_environment
def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
"""
Create a Pylons WSGI application and return it
``global_conf``
The inherited configuration for this application. Normally from
the [DEFAULT] section of the Paste ini file.
``full_stack``
Whether this application provides a full WSGI stack (by default,
meaning it handles its own exceptions and errors). Disable
full_stack when this application is "managed" by another WSGI
middleware.
``static_files``
Whether this application serves its own static files; disable
when another web server is responsible for serving them.
``app_conf``
The application's local configuration. Normally specified in
the [app:<name>] section of the Paste ini file (where <name>
defaults to main).
"""
# Configure the Pylons environment
load_environment(global_conf, app_conf)
# The Pylons WSGI app
app = PylonsApp()
# Routing/Session/Cache Middleware
app = RoutesMiddleware(app, config['routes.map'])
app = SessionMiddleware(app, config)
app = CacheMiddleware(app, config)
# CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
if asbool(full_stack):
# Handle Python exceptions
app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
app = Observer(app)
# Display error documents for 401, 403, 404 status codes (and
# 500 when debug is disabled)
if asbool(config['debug']):
app = StatusCodeRedirect(app, [400, 401, 403, 404], '/content/pagenotfound')
else:
app = StatusCodeRedirect(app, [400, 401, 403, 404, 500], '/content/pagenotfound')
# Establish the Registry for this application
app = RegistryManager(app)
if asbool(static_files):
# Serve static files
static_app = StaticURLParser(config['pylons.paths']['static_files'])
app = Cascade([static_app, app])
app = StripTrailingSlash(app)
return app
另外 Observer.py 类
from pylons.util import call_wsgi_application
from webob import Request, Response
from weberror import formatter, collector
class Observer(object):
""" Observer object to monitor and extract the traceback for 'pagenotfound' emails """
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
status, headers, app_iter, exc_info = call_wsgi_application(
self.app, environ, catch_exc_info=True)
if exc_info is not None:
exc_data = collector.collect_exception(*exc_info)
err_report = formatter.format_text(exc_data, show_hidden_frames=True)[0]
environ['err_report'] = err_report
start_response(status, headers, exc_info)
return app_iter
,这是 Error.py
import cgi
from paste.urlparser import PkgResourcesParser
from pylons import request
from pylons.controllers.util import forward
from pylons.middleware import error_document_template
from webhelpers.html.builder import literal
from r4l.lib.base import BaseController
from r4l.lib import helpers as h
class ErrorController(BaseController):
"""Generates error documents as and when they are required.
The ErrorDocuments middleware forwards to ErrorController when error
related status codes are returned from the application.
This behaviour can be altered by changing the parameters to the
ErrorDocuments middleware in your config/middleware.py file.
"""
def document(self):
"""Render the error document"""
resp = request.environ.get('pylons.original_response')
if resp.status_int == 404:
h.redirect_to('/content/pagenotfound')
content = literal(resp.body) or cgi.escape(request.GET.get('message', ''))
page = error_document_template % \
dict(prefix=request.environ.get('SCRIPT_NAME', ''),
code=cgi.escape(request.GET.get('code', str(resp.status_int))),
message=content)
return page
def img(self, id):
"""Serve Pylons' stock images"""
return self._serve_file('/'.join(['media/img', id]))
def style(self, id):
"""Serve Pylons' stock stylesheets"""
return self._serve_file('/'.join(['media/style', id]))
def _serve_file(self, path):
"""Call Paste's FileApp (a WSGI application) to serve the file
at the specified path
"""
request.environ['PATH_INFO'] = '/%s' % path
return forward(PkgResourcesParser('pylons', 'pylons'))
最后是 pagenotfound func 的控制器
@h.template(u'content/404')
def pagenotfound(self):
"""
Default pagenotfound page
"""
c.err_report = str(request.environ.get('pylons.original_response','')) + '\n\n'
if 'err_report' in request.environ:
c.err_report += request.environ.get('err_report','')
log.info("###### c.err_report: %s" % c.err_report)
c.page_title = u'Page Not Found'
c.previous_url = request.environ.get('HTTP_REFERER', h.url_for('/'))
pagenotfound = True
session['pagenotfound'] = pagenotfound
session.save()
if c.login:
user = Session.query(User).get(session[u'username'])
if user:
c.login.email = user.contactemail.value
这是未被捕获的异常:
文件“/home/chilton/work/cj2/CJ-7519/r4l/templates/resume/preview.html”,第 441 行
${h.cj_month_year(employment.startdate)} - 当前${employment.enddate.strftime('%m/%Y')} ValueError:year=200是1900年之前;日期时间 strftime() 方法要求年份 >= 1900
我尝试过寻找不同的方法来解决这个问题,但没有成功。
I get this ugly "Internal Server Error" when I should be getting a neat 'page not found' page when an internal Pylons:python error occurs.
I have simulated a Python error elsewhere & the correct pagenotfound template is generated. In my config (development.ini): debug = false, full_stack = true ... so as to render this page when an exception occurs.
This is how the middleware.py looks currently:
"""Pylons middleware initialization"""
from beaker.middleware import CacheMiddleware, SessionMiddleware
from paste.cascade import Cascade
from paste.registry import RegistryManager
from paste.urlparser import StaticURLParser
from paste.deploy.converters import asbool
from pylons import config
from pylons.middleware import ErrorHandler, StatusCodeRedirect
from observer import Observer
from pylons.wsgiapp import PylonsApp
from routes.middleware import RoutesMiddleware
from r4l.lib.components.middleware.striptrailingslash import StripTrailingSlash
from r4l.config.environment import load_environment
def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
"""
Create a Pylons WSGI application and return it
``global_conf``
The inherited configuration for this application. Normally from
the [DEFAULT] section of the Paste ini file.
``full_stack``
Whether this application provides a full WSGI stack (by default,
meaning it handles its own exceptions and errors). Disable
full_stack when this application is "managed" by another WSGI
middleware.
``static_files``
Whether this application serves its own static files; disable
when another web server is responsible for serving them.
``app_conf``
The application's local configuration. Normally specified in
the [app:<name>] section of the Paste ini file (where <name>
defaults to main).
"""
# Configure the Pylons environment
load_environment(global_conf, app_conf)
# The Pylons WSGI app
app = PylonsApp()
# Routing/Session/Cache Middleware
app = RoutesMiddleware(app, config['routes.map'])
app = SessionMiddleware(app, config)
app = CacheMiddleware(app, config)
# CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
if asbool(full_stack):
# Handle Python exceptions
app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
app = Observer(app)
# Display error documents for 401, 403, 404 status codes (and
# 500 when debug is disabled)
if asbool(config['debug']):
app = StatusCodeRedirect(app, [400, 401, 403, 404], '/content/pagenotfound')
else:
app = StatusCodeRedirect(app, [400, 401, 403, 404, 500], '/content/pagenotfound')
# Establish the Registry for this application
app = RegistryManager(app)
if asbool(static_files):
# Serve static files
static_app = StaticURLParser(config['pylons.paths']['static_files'])
app = Cascade([static_app, app])
app = StripTrailingSlash(app)
return app
Also Observer.py class
from pylons.util import call_wsgi_application
from webob import Request, Response
from weberror import formatter, collector
class Observer(object):
""" Observer object to monitor and extract the traceback for 'pagenotfound' emails """
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
status, headers, app_iter, exc_info = call_wsgi_application(
self.app, environ, catch_exc_info=True)
if exc_info is not None:
exc_data = collector.collect_exception(*exc_info)
err_report = formatter.format_text(exc_data, show_hidden_frames=True)[0]
environ['err_report'] = err_report
start_response(status, headers, exc_info)
return app_iter
this is the Error.py
import cgi
from paste.urlparser import PkgResourcesParser
from pylons import request
from pylons.controllers.util import forward
from pylons.middleware import error_document_template
from webhelpers.html.builder import literal
from r4l.lib.base import BaseController
from r4l.lib import helpers as h
class ErrorController(BaseController):
"""Generates error documents as and when they are required.
The ErrorDocuments middleware forwards to ErrorController when error
related status codes are returned from the application.
This behaviour can be altered by changing the parameters to the
ErrorDocuments middleware in your config/middleware.py file.
"""
def document(self):
"""Render the error document"""
resp = request.environ.get('pylons.original_response')
if resp.status_int == 404:
h.redirect_to('/content/pagenotfound')
content = literal(resp.body) or cgi.escape(request.GET.get('message', ''))
page = error_document_template % \
dict(prefix=request.environ.get('SCRIPT_NAME', ''),
code=cgi.escape(request.GET.get('code', str(resp.status_int))),
message=content)
return page
def img(self, id):
"""Serve Pylons' stock images"""
return self._serve_file('/'.join(['media/img', id]))
def style(self, id):
"""Serve Pylons' stock stylesheets"""
return self._serve_file('/'.join(['media/style', id]))
def _serve_file(self, path):
"""Call Paste's FileApp (a WSGI application) to serve the file
at the specified path
"""
request.environ['PATH_INFO'] = '/%s' % path
return forward(PkgResourcesParser('pylons', 'pylons'))
And finally the controller for pagenotfound func
@h.template(u'content/404')
def pagenotfound(self):
"""
Default pagenotfound page
"""
c.err_report = str(request.environ.get('pylons.original_response','')) + '\n\n'
if 'err_report' in request.environ:
c.err_report += request.environ.get('err_report','')
log.info("###### c.err_report: %s" % c.err_report)
c.page_title = u'Page Not Found'
c.previous_url = request.environ.get('HTTP_REFERER', h.url_for('/'))
pagenotfound = True
session['pagenotfound'] = pagenotfound
session.save()
if c.login:
user = Session.query(User).get(session[u'username'])
if user:
c.login.email = user.contactemail.value
This is the exception that is not being caught:
File '/home/chilton/work/cj2/CJ-7519/r4l/templates/resume/preview.html', line 441 in
${h.cj_month_year(employment.startdate)} - Current${employment.enddate.strftime('%m/%Y')} ValueError: year=200 is before 1900; the datetime strftime() methods require year >= 1900
I've tried looking at different ways of solving this one, but without success.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论