summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Bicking <ian@ianbicking.org>2005-08-22 19:19:10 +0000
committerIan Bicking <ian@ianbicking.org>2005-08-22 19:19:10 +0000
commite2287121fc3948ce64d26f7cd6516831b36b4543 (patch)
tree9df14fecb401af7000887f546b165e5e55621d51
parent286a5da8ee0572f486ff95a43e59d45e2c928f9a (diff)
downloadpaste-git-e2287121fc3948ce64d26f7cd6516831b36b4543.tar.gz
Move around tests and exceptions; more moving to come, hence this intermediate (broken) commit
-rw-r--r--paste/exceptions/errormiddleware.py (renamed from paste/errormiddleware.py)96
-rw-r--r--paste/exceptions/test_error_middleware.py (renamed from paste/tests/test_error_middleware.py)15
-rw-r--r--paste/fixture.py (renamed from paste/tests/fixture.py)95
-rw-r--r--setup.cfg3
-rw-r--r--setup.py10
5 files changed, 95 insertions, 124 deletions
diff --git a/paste/errormiddleware.py b/paste/exceptions/errormiddleware.py
index 2ff2007..0f4541c 100644
--- a/paste/errormiddleware.py
+++ b/paste/exceptions/errormiddleware.py
@@ -1,5 +1,5 @@
"""
-Error handler middleware, and paste.config reporter integration
+Error handler middleware
"""
import sys
import traceback
@@ -11,9 +11,14 @@ except ImportError:
from paste.exceptions import formatter, collector, reporter
from paste import wsgilib
from paste.docsupport import metadata
+import pkg_resources
+from paste.deploy import converters
__all__ = ['ErrorMiddleware', 'handle_exception']
+class NoDefault:
+ pass
+
class ErrorMiddleware(object):
"""
@@ -37,24 +42,38 @@ class ErrorMiddleware(object):
want errors to be caught and transformed.
"""
- _config_debug = metadata.Config(
- """If true, show errors in the browser""", default=False)
- _config_error_email = metadata.Config(
- """
- The email address to send errors to (defining this enables
- the emailing of errors)""", default=None)
- _config_error_log = metadata.Config(
- """
- A filename to write errors to.
- """, default=None)
- _config_show_exceptions_in_error_log = metadata.Config(
- """
- If true, then write errors to ``wsgi.errors``.
- """, default=False)
-
- def __init__(self, application):
+ def __init__(self, application, global_conf,
+ debug=NoDefault,
+ error_email=None,
+ error_log=None,
+ show_exceptions_in_wsgi_errors=False,
+ from_address=None,
+ smtp_server=None,
+ error_subject_prefix=None,
+ error_message=None):
self.application = application
-
+ if debug is NoDefault:
+ debug = global_conf.get('debug')
+ self.debug_mode = converters.asbool(debug)
+ if error_email is None:
+ error_email = (global_conf.get('error_email')
+ or global_conf.get('admin_email')
+ or global_conf.get('webmaster_email')
+ or global_conf.get('sysadmin_email'))
+ self.error_email = converters.aslist(error_email)
+ self.error_log = error_log
+ self.show_exceptions_in_wsgi_errors = show_exceptions_in_wsgi_errors
+ if from_address is None:
+ from_address = global_conf.get('error_from_address', 'errors@localhost')
+ self.from_address = from_address
+ if smtp_server is None:
+ smtp_server = global_conf.get('smtp_server', 'localhost')
+ self.smtp_server = smtp_server
+ self.error_subject_prefix = error_subject_prefix or ''
+ if error_message is None:
+ error_message = global_conf.get('error_message')
+ self.error_message = error_message
+
def __call__(self, environ, start_response):
# We want to be careful about not sending headers twice,
# and the content type that the app has committed to (if there
@@ -111,8 +130,16 @@ class ErrorMiddleware(object):
def exception_handler(self, exc_info, environ):
return handle_exception(
- exc_info, environ['paste.config'], environ['wsgi.errors'],
- html=True)
+ exc_info, environ['wsgi.errors'],
+ html=True,
+ debug_mode=self.debug_mode,
+ error_email=self.error_email,
+ error_log=self.error_log,
+ show_exceptions_in_wsgi_errors=self.show_exceptions_in_wsgi_errors,
+ error_email_from=self.error_email_from,
+ smtp_server=self.smtp_server,
+ error_subject_prefix=self.error_subject_prefix,
+ error_message=self.error_message)
class Supplement(object):
def __init__(self, middleware, environ):
@@ -156,7 +183,15 @@ class Supplement(object):
(1, 1, 1): 'Multi thread/process CGI (?)',
}
-def handle_exception(exc_info, conf, error_stream, html=True):
+def handle_exception(exc_info, error_stream, html=True,
+ debug_mode=False,
+ error_email=None,
+ error_log=None,
+ show_exceptions_in_wsgi_errors=False
+ error_email_from='errors@localhost',
+ smtp_server='localhost',
+ error_subject_prefix='',
+ ):
"""
You can also use exception handling outside of a web context,
like::
@@ -177,26 +212,26 @@ def handle_exception(exc_info, conf, error_stream, html=True):
reported = False
exc_data = collector.collect_exception(*exc_info)
extra_data = ''
- if conf.get('error_email'):
+ if error_email:
rep = reporter.EmailReporter(
- to_addresses=conf['error_email'],
- from_address=conf.get('error_email_from', 'errors@localhost'),
- smtp_server=conf.get('smtp_server', 'localhost'),
- subject_prefix=conf.get('error_subject_prefix', ''))
+ to_addresses=error_email,
+ from_address=error_email_from,
+ smtp_server=smtp_server,
+ subject_prefix=error_subject_prefix)
rep_err = send_report(rep, exc_data, html=html)
if rep_err:
extra_data += rep_err
else:
reported = True
- if conf.get('error_log'):
+ if error_log:
rep = reporter.LogReporter(
- filename=conf['error_log'])
+ filename=error_log)
rep_err = send_report(rep, exc_data, html=html)
if rep_err:
extra_data += rep_err
else:
reported = True
- if conf.get('show_exceptions_in_error_log', False):
+ if show_exceptions_in_wsgi_errors:
rep = reporter.FileReporter(
file=error_stream)
rep_err = send_report(rep, exc_data, html=html)
@@ -208,7 +243,7 @@ def handle_exception(exc_info, conf, error_stream, html=True):
error_stream.write('Error - %s: %s\n' % (
exc_data.exception_type, exc_data.exception_value))
if html:
- if conf.get('debug', False):
+ if debug_mode:
error_html = formatter.format_html(exc_data,
include_hidden_frames=True)
return_error = error_template(
@@ -216,7 +251,6 @@ def handle_exception(exc_info, conf, error_stream, html=True):
extra_data = ''
reported = True
else:
- error_message = conf.get('error_message')
return_error = error_template(
error_message or '''
An error occurred. See the error logs for more information.
diff --git a/paste/tests/test_error_middleware.py b/paste/exceptions/test_error_middleware.py
index 6ad9aba..956aa26 100644
--- a/paste/tests/test_error_middleware.py
+++ b/paste/exceptions/test_error_middleware.py
@@ -3,11 +3,16 @@ from paste.errormiddleware import ErrorMiddleware
from paste import lint
def do_request(app, expect_status=500):
- res = fake_request(ErrorMiddleware(lint.middleware(app)),
- **{'paste.config': {'debug': True}})
- assert res.status_int == expect_status
+ app = lint.middleware(app)
+ app = ErrorMiddleware(app, {}, debug=True)
+ testapp = TestApp(app)
+ res = TestApp.get('', status=expect_status)
return res
+############################################################
+## Applications that raise exceptions
+############################################################
+
def bad_app():
"No argument list!"
return None
@@ -30,6 +35,10 @@ def yielder(args):
raise ValueError("None raises error")
yield arg
+############################################################
+## Tests
+############################################################
+
def test_makes_exception():
res = do_request(bad_app)
print res
diff --git a/paste/tests/fixture.py b/paste/fixture.py
index 3a27b62..9016c18 100644
--- a/paste/tests/fixture.py
+++ b/paste/fixture.py
@@ -91,85 +91,6 @@ def sorted(l):
l.sort()
return l
-def fake_request(application, path_info='', use_lint=True, **environ):
- """
- Runs the application in a fake environment, returning a response object
- """
- if use_lint:
- application = lint.middleware(application)
- status, headers, body, errors = wsgilib.raw_interactive(
- application, path_info, **environ)
- res = FakeResponse(status, headers, body, errors)
- if res.errors:
- print 'Errors:'
- print res.errors
- return res
-
-class FakeResponse(object):
-
- def __init__(self, status, headers, body, errors):
- self.status = status
- self.headers = headers
- self.body = body
- self.errors = errors
-
- def status_int__get(self):
- return int(self.status.split()[0])
- status_int = property(status_int__get)
-
- def all_ok(self):
- """
- Asserts that there were no errors and the status was 200 OK
- """
- assert not self.errors, (
- "Response had errors: %s" % self.errors)
- assert self.status_int == 200, (
- "Response did not return 200 OK: %r" % self.status)
-
- def header(self, name, default=NoDefault):
- """
- Returns the named header; an error if there is not exactly one
- matching header (unless you give a default -- always an error if
- there is more than one header)
- """
- found = None
- for cur_name, value in self.headers:
- if cur_name.lower() == name.lower():
- assert not found, (
- "Ambiguous header: %s matches %r and %r"
- % (name, found, value))
- found = value
- if found is None:
- if default is NoDefault:
- raise KeyError(
- "No header found: %r (from %s)"
- % (name, ', '.join([n for n, v in self.headers])))
- else:
- return default
- return found
-
- def all_headers(self, name):
- """
- Gets all headers, returns as a list
- """
- found = []
- for cur_name, value in self.headers:
- if cur_name.lower() == name.lower():
- found.append(value)
- return found
-
- def __contains__(self, s):
- return self.body.find(s) != -1
-
- def __repr__(self):
- return '<Response %s %r>' % (self.status, self.body[:20])
-
- def __str__(self):
- return 'Response: %s\n%s\n%s' % (
- self.status,
- '\n'.join(['%s: %s' % (n, v) for n, v in self.headers]),
- self.body)
-
class Dummy_smtplib(object):
existing = None
@@ -272,17 +193,22 @@ class TestApp(object):
# for py.test
disabled = True
- def __init__(self, app, config={}, namespace=None):
+ def __init__(self, app, namespace=None, relative_to=None):
+ if isinstance(app, (str, unicode)):
+ from paste.deploy import loadapp
+ # @@: Should pick up relative_to from calling module's
+ # __file__
+ app = loadapp(app, relative_to=relative_to)
self.app = app
- self.config = config
self.namespace = namespace
+ self.relative_to = relative_to
self.reset()
def reset(self):
self.cookies = {}
def make_environ(self):
- environ = self.config.get('test_environ', {}).copy()
+ environ = {}
environ['paste.throw_errors'] = True
return environ
@@ -356,9 +282,8 @@ class TestApp(object):
if len(file_info) == 2:
# It only has a filename
filename = file_info[2]
- if self.config.get('test_file_path'):
- filename = os.path.join(self.config['test_file_path'],
- filename)
+ if self.relative_to:
+ filename = os.path.join(self.relative_to, filename)
f = open(filename, 'rb')
content = f.read()
f.close()
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..01bb954
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,3 @@
+[egg_info]
+tag_build = dev
+tag_svn_revision = true
diff --git a/setup.py b/setup.py
index 467cd3f..1d3e294 100644
--- a/setup.py
+++ b/setup.py
@@ -44,11 +44,11 @@ functionality.
'paste.app_templates': ['*.*_tmpl'],
},
zip_safe=False,
- extras_require={'Examples': ['SQLObject', 'ZopePageTemplates', 'Component',
- 'ZPTKit', 'SQLObject', 'pysqlite'],
- 'HTTP': ['WSGI_Utils'],
- 'SCGI': ['flup'],
- }
+ entry_points={
+ 'paste.filter_app_factory1': """
+ error_catcher=paste.exceptions.errormiddleware:ErrorMiddleware
+ """,
+ },
)
# Send announce to: