# HG changeset patch # User paulb # Date 1163720431 0 # Node ID 682241c90f491e15ca382a41a24482866f9400a6 # Parent d7000fde266adda741268ff3f2500ef34c5990d8 [project @ 2006-11-16 23:40:31 by paulb] Added rollback method and error resource usage for better error reporting. diff -r d7000fde266a -r 682241c90f49 WebStack/Adapters/BaseHTTPRequestHandler.py --- a/WebStack/Adapters/BaseHTTPRequestHandler.py Thu Nov 16 23:40:10 2006 +0000 +++ b/WebStack/Adapters/BaseHTTPRequestHandler.py Thu Nov 16 23:40:31 2006 +0000 @@ -3,7 +3,7 @@ """ BaseHTTPRequestHandler adapter. -Copyright (C) 2004, 2005 Paul Boddie +Copyright (C) 2004, 2005, 2006 Paul Boddie This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -23,46 +23,51 @@ import WebStack.BaseHTTPRequestHandler import BaseHTTPServer from WebStack.Generic import EndOfResponse +from WebStack.Adapters.Helpers.Error import ErrorResource class HandlerFactory: "A factory class creating WebStack dispatcher objects." - def __init__(self, resource, authenticator=None, handle_errors=1): + def __init__(self, resource, authenticator=None, handle_errors=1, error_resource=None): """ Initialise the root application-specific 'resource' and optional 'authenticator'. The optional 'handle_errors' parameter (if true) causes - handlers to deal with uncaught exceptions cleanly. + handlers to deal with uncaught exceptions cleanly, and the optional + 'error_resource' specifies an alternative error message generation + resource. """ self.webstack_resource = resource self.webstack_authenticator = authenticator self.handle_errors = handle_errors + self.error_resource = error_resource or ErrorResource() def __call__(self, request, client_address, server): "Act as a factory for the server objects." handler = Handler(request, client_address, server, self.webstack_resource, - self.webstack_authenticator, self.handle_errors) + self.webstack_authenticator, self.handle_errors, self.error_resource) return handler class Handler(BaseHTTPServer.BaseHTTPRequestHandler): "A class dispatching requests to WebStack resources." - def __init__(self, request, client_address, server, resource, authenticator, handle_errors): + def __init__(self, request, client_address, server, resource, authenticator, handle_errors, error_resource): """ Initialise the root application-specific 'resource' and 'authenticator'. Where 'handle_errors' is true, uncaught exceptions are dealt with by the - handler. + handler and reported using the 'error_resource' provided. """ self.webstack_resource = resource self.webstack_authenticator = authenticator self.handle_errors = handle_errors + self.error_resource = error_resource BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, request, client_address, server) def handle(self): @@ -84,7 +89,9 @@ pass except: if self.handle_errors: + trans.rollback() trans.set_response_code(500) # Internal error + self.error_resource.respond(trans) else: raise else: @@ -97,7 +104,7 @@ default_address = ("", 8080) -def deploy(resource, authenticator=None, address=None, handle_errors=1): +def deploy(resource, authenticator=None, address=None, handle_errors=1, error_resource=None): """ Deploy the given 'resource', with the given optional 'authenticator', at the @@ -105,10 +112,11 @@ (host_string, port_integer). The optional 'handle_errors' flag (true by default) specifies whether error - conditions are handled gracefully. + conditions are handled gracefully, and the optional 'error_resource' + specifies an alternative error message generation resource, if desired. """ - handler = HandlerFactory(resource, authenticator, handle_errors) + handler = HandlerFactory(resource, authenticator, handle_errors, error_resource) server = BaseHTTPServer.HTTPServer(address or default_address, handler) server.serve_forever() diff -r d7000fde266a -r 682241c90f49 WebStack/Adapters/CGI.py --- a/WebStack/Adapters/CGI.py Thu Nov 16 23:40:10 2006 +0000 +++ b/WebStack/Adapters/CGI.py Thu Nov 16 23:40:31 2006 +0000 @@ -23,9 +23,10 @@ import WebStack.CGI from WebStack.Generic import EndOfResponse import sys, os +from WebStack.Adapters.Helpers.Error import ErrorResource def deploy(resource, authenticator=None, input=None, output=None, env=None, - address=None, handle_errors=1): + address=None, handle_errors=1, error_resource=None): """ Dispatch to the root application-specific 'resource'. Employ the optional @@ -34,11 +35,15 @@ of the defaults: standard input, standard output and the operating system environment respectively. Note that 'env' must evaluate to true for it to replace the default. The optional 'handle_errors' parameter (if true) causes - handlers to deal with uncaught exceptions cleanly. + handlers to deal with uncaught exceptions cleanly, and the optional + 'error_resource' specifies an alternative error message generation resource, + if desired. The optional 'address' parameter is deliberately ignored. """ + error_resource = error_resource or ErrorResource() + trans = WebStack.CGI.Transaction(input or sys.stdin, output or sys.stdout, env or os.environ) @@ -50,7 +55,9 @@ pass except: if handle_errors: + trans.rollback() trans.set_response_code(500) # Internal error + error_resource.respond(trans) else: raise else: diff -r d7000fde266a -r 682241c90f49 WebStack/Adapters/Django.py --- a/WebStack/Adapters/Django.py Thu Nov 16 23:40:10 2006 +0000 +++ b/WebStack/Adapters/Django.py Thu Nov 16 23:40:31 2006 +0000 @@ -22,23 +22,27 @@ import WebStack.Django from WebStack.Generic import EndOfResponse +from WebStack.Adapters.Helpers.Error import ErrorResource -def deploy(resource, authenticator=None, address=None, handle_errors=1): +def deploy(resource, authenticator=None, address=None, handle_errors=1, error_resource=None): """ Deploy the given 'resource', employing the optional 'authenticator' to protect it. The optional 'handle_errors' parameter (if true) causes handlers - to deal with uncaught exceptions cleanly. + to deal with uncaught exceptions cleanly, and the optional 'error_resource' + specifies an alternative error message generation resource, if desired. The optional 'address' parameter is deliberately ignored. """ def _deploy(request, *args, **kw): return respond(request, resource, authenticator=authenticator, - virtual_path_info=kw.get("vp"), handle_errors=handle_errors) + virtual_path_info=kw.get("vp"), handle_errors=handle_errors, + error_resource=error_resource) return _deploy -def respond(request, resource, authenticator=None, virtual_path_info=None, handle_errors=1): +def respond(request, resource, authenticator=None, virtual_path_info=None, handle_errors=1, + error_resource=None): """ Dispatch to the root application-specific 'resource'. Employ the optional @@ -47,9 +51,12 @@ given 'resource'. The optional 'handle_errors' parameter (if true) causes handlers to deal - with uncaught exceptions cleanly. + with uncaught exceptions cleanly, and the optional 'error_resource' + specifies an alternative error message generation resource. """ + error_resource = error_resource or ErrorResource() + trans = WebStack.Django.Transaction(request) if virtual_path_info: trans.set_virtual_path_info(virtual_path_info) @@ -62,7 +69,9 @@ pass except Exception, exc: if handle_errors: + trans.rollback() trans.set_response_code(500) # Internal error + error_resource.respond(trans) else: raise else: diff -r d7000fde266a -r 682241c90f49 WebStack/Adapters/WSGI.py --- a/WebStack/Adapters/WSGI.py Thu Nov 16 23:40:10 2006 +0000 +++ b/WebStack/Adapters/WSGI.py Thu Nov 16 23:40:31 2006 +0000 @@ -3,7 +3,7 @@ """ WSGI adapter. -Copyright (C) 2004, 2005 Paul Boddie +Copyright (C) 2004, 2005, 2006 Paul Boddie This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -23,22 +23,26 @@ import WebStack.WSGI from WebStack.Generic import EndOfResponse from WebStack.Adapters.Helpers.wsgi_cgi import run_with_cgi +from WebStack.Adapters.Helpers.Error import ErrorResource class WSGIAdapter: "A WSGI adapter class." - def __init__(self, resource, authenticator=None, handle_errors=1): + def __init__(self, resource, authenticator=None, handle_errors=1, error_resource=None): """ Initialise the adapter with the given WebStack 'resource' and the optional 'authenticator'. The optional 'handle_errors' parameter (if - true) causes handlers to deal with uncaught exceptions cleanly. + true) causes handlers to deal with uncaught exceptions cleanly, and the + optional 'error_resource' specifies an alternative error message + generation resource. """ self.resource = resource self.authenticator = authenticator self.handle_errors = handle_errors + self.error_resource = error_resource or ErrorResource() def __call__(self, environ, start_response): @@ -64,7 +68,9 @@ pass except: if self.handle_errors: + trans.rollback() trans.set_response_code(500) # Internal error + self.error_resource.respond(trans) else: raise else: @@ -83,7 +89,7 @@ ) return [trans.get_wsgi_content()] -def deploy(resource, authenticator=None, address=None, handle_errors=1): +def deploy(resource, authenticator=None, address=None, handle_errors=1, error_resource=None): """ Deploy the given 'resource', with the given optional 'authenticator', at the @@ -93,10 +99,11 @@ NOTE: The 'address' is ignored with the current WSGI implementation. The optional 'handle_errors' flag (true by default) specifies whether error - conditions are handled gracefully. + conditions are handled gracefully, and the optional 'error_resource' + specifies an alternative error message generation resource, if desired. """ - handler = WSGIAdapter(resource, authenticator, handle_errors) + handler = WSGIAdapter(resource, authenticator, handle_errors, error_resource) run_with_cgi(handler) # vim: tabstop=4 expandtab shiftwidth=4