summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorianb <devnull@localhost>2005-12-05 09:26:15 +0000
committerianb <devnull@localhost>2005-12-05 09:26:15 +0000
commit229f197a9cacea3892f3b4a042d72ddb83464cae (patch)
treece22d54fbc11bbf70212dffe2461a34dcfc120b7
parentc6944a849d21424c4ff68c70d46fc7c325a2dfa0 (diff)
downloadpaste-229f197a9cacea3892f3b4a042d72ddb83464cae.tar.gz
Put in reduced-content exceptions for XMLHttpRequest responses, marked by the presence of a _ GET variable
-rw-r--r--paste/evalexception/evalcontext.py5
-rw-r--r--paste/evalexception/middleware.py28
-rw-r--r--paste/exceptions/errormiddleware.py29
3 files changed, 51 insertions, 11 deletions
diff --git a/paste/evalexception/evalcontext.py b/paste/evalexception/evalcontext.py
index 2b96126..5ce311d 100644
--- a/paste/evalexception/evalcontext.py
+++ b/paste/evalexception/evalcontext.py
@@ -17,8 +17,9 @@ class EvalContext(object):
doctest.
"""
- def __init__(self, namespace):
+ def __init__(self, namespace, globs):
self.namespace = namespace
+ self.globs = globs
def exec_expr(self, s):
out = StringIO()
@@ -31,7 +32,7 @@ class EvalContext(object):
sys.stdout = out
try:
code = compile(s, '<web>', "single", 0, 1)
- exec code in self.namespace
+ exec code in self.namespace, self.globs
debugger.set_continue()
except KeyboardInterrupt:
raise
diff --git a/paste/evalexception/middleware.py b/paste/evalexception/middleware.py
index 69b5c44..6c10f08 100644
--- a/paste/evalexception/middleware.py
+++ b/paste/evalexception/middleware.py
@@ -142,9 +142,13 @@ debug_counter = itertools.count(int(time.time()))
class EvalException(object):
- def __init__(self, application, global_conf=None):
+ def __init__(self, application, global_conf=None,
+ xmlhttp_key=None):
self.application = application
self.debug_infos = {}
+ if xmlhttp_key is None:
+ xmlhttp_key = global_conf.get('xmlhttp_key', '_')
+ self.xmlhttp_key = xmlhttp_key
def __call__(self, environ, start_response):
assert not environ['wsgi.multiprocess'], (
@@ -203,7 +207,8 @@ class EvalException(object):
input = input.rstrip() + '\n'
frame = debug_info.frame(int(tbid))
vars = frame.tb_frame.f_locals
- context = evalcontext.EvalContext(vars)
+ glob_vars = frame.tb_frame.f_globals
+ context = evalcontext.EvalContext(vars, glob_vars)
output = context.exec_expr(input)
input_html = formatter.str2html(input)
return ('<code style="color: #060">&gt;&gt;&gt;</code> '
@@ -233,14 +238,25 @@ class EvalException(object):
for expected in environ.get('paste.expected_exceptions', []):
if issubclass(exc_info[0], expected):
raise
- count = debug_counter.next()
- debug_info = DebugInfo(count, exc_info)
- assert count not in self.debug_infos
- self.debug_infos[count] = debug_info
+
if not started:
start_response('500 Internal Server Error',
[('content-type', 'text/html')],
exc_info)
+
+ if self.xmlhttp_key:
+ get_vars = wsgilib.parse_querystring(environ)
+ if dict(get_vars).get(self.xmlhttp_key):
+ exc_data = collector.collect_exception(*exc_info)
+ html = formatter.format_html(
+ exc_data, include_hidden_frames=False,
+ include_reusable=False, show_extra_data=False)
+ return [html]
+
+ count = debug_counter.next()
+ debug_info = DebugInfo(count, exc_info)
+ assert count not in self.debug_infos
+ self.debug_infos[count] = debug_info
# @@: it would be nice to deal with bad content types here
exc_data = collector.collect_exception(*exc_info)
html = format_eval_html(exc_data, base_path, count)
diff --git a/paste/exceptions/errormiddleware.py b/paste/exceptions/errormiddleware.py
index 1060af2..0a21cf0 100644
--- a/paste/exceptions/errormiddleware.py
+++ b/paste/exceptions/errormiddleware.py
@@ -58,6 +58,13 @@ class ErrorMiddleware(object):
``error_message``:
When debug mode is off, the error message to show to users.
+ ``xmlhttp_key``:
+
+ When this key (default ``_``) is in the request GET variables
+ (not POST!), expect that this is an XMLHttpRequest, and the
+ response should be more minimal; it should not be a complete
+ HTML page.
+
This also looks for a special key ``'paste.expected_exceptions``,
which should be a list of exception classes. When an exception is
raised, if it is found in this list then it will be re-raised
@@ -74,7 +81,8 @@ class ErrorMiddleware(object):
from_address=None,
smtp_server=None,
error_subject_prefix=None,
- error_message=None):
+ error_message=None,
+ xmlhttp_key=None):
self.application = application
if global_conf is None:
global_conf = {}
@@ -99,6 +107,9 @@ class ErrorMiddleware(object):
if error_message is None:
error_message = global_conf.get('error_message')
self.error_message = error_message
+ if xmlhttp_key is None:
+ xmlhttp_key = global_conf.get('xmlhttp_key', '_')
+ self.xmlhttp_key = xmlhttp_key
def __call__(self, environ, start_response):
"""
@@ -161,6 +172,11 @@ class ErrorMiddleware(object):
yield response
def exception_handler(self, exc_info, environ):
+ simple_html_error = False
+ if self.xmlhttp_key:
+ get_vars = wsgilib.parse_querystring(environ)
+ if dict(get_vars).get(self.xmlhttp_key):
+ simple_html_error = True
return handle_exception(
exc_info, environ['wsgi.errors'],
html=True,
@@ -171,7 +187,8 @@ class ErrorMiddleware(object):
error_email_from=self.from_address,
smtp_server=self.smtp_server,
error_subject_prefix=self.error_subject_prefix,
- error_message=self.error_message)
+ error_message=self.error_message,
+ simple_html_error=simple_html_error)
class Supplement(object):
@@ -232,6 +249,7 @@ def handle_exception(exc_info, error_stream, html=True,
smtp_server='localhost',
error_subject_prefix='',
error_message=None,
+ simple_html_error=False,
):
"""
For exception handling outside of a web context
@@ -285,7 +303,12 @@ def handle_exception(exc_info, error_stream, html=True,
error_stream.write('Error - %s: %s\n' % (
exc_data.exception_type, exc_data.exception_value))
if html:
- if debug_mode:
+ if debug_mode and simple_html_error:
+ return_error = formatter.format_html(
+ exc_data, include_hidden_frames=False,
+ include_reusable=False, show_extra_data=False)
+ reported = True
+ elif debug_mode and not simple_html_error:
error_html = formatter.format_html(
exc_data,
include_hidden_frames=True,