diff options
author | Ian Bicking <ian@ianbicking.org> | 2005-08-22 19:19:10 +0000 |
---|---|---|
committer | Ian Bicking <ian@ianbicking.org> | 2005-08-22 19:19:10 +0000 |
commit | e2287121fc3948ce64d26f7cd6516831b36b4543 (patch) | |
tree | 9df14fecb401af7000887f546b165e5e55621d51 | |
parent | 286a5da8ee0572f486ff95a43e59d45e2c928f9a (diff) | |
download | paste-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.cfg | 3 | ||||
-rw-r--r-- | setup.py | 10 |
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 @@ -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: |