durusmail: quixote-users: Exception-handling patch for medusa_http.py
Exception-handling patch for medusa_http.py
2003-01-17
A better patch (Re: Exception-handling patch for medusa_http.py)
2003-01-17
A better patch (Re: Exception-handling patch for medusa_http.py)
2003-01-20
Re: A better patch (Re: Exception-handling patch for medusa_http.py)
2003-01-20
2003-01-17
Exception-handling patch for medusa_http.py
Graham Fawcett
2003-01-17
While trying out the SessionPublisher with medusa_http.py, the
QuixoteHandler did not catch and handle a SessionError that the
SessionPublisher raised. Instead, the exception was handled by Medusa
itself, resulting in a rather meaningless 500 error being returned to my
client.

I think the following patch handles the exception in Quixotic fashion,
via a call to finish_interrupted_request().

For my own needs, I also added two additional environment variables to
the handler, ACCEPT_ENCODING and USER_AGENT. (There were a couple tabs
mixed in the source too, looks like they got fixed.)


diff -U 2 C:\projects\Quixote-0.6b1\server\medusa_http.py
C:\Python22\Lib\site-packages\quixote\server\medusa_http.py
--- C:\projects\Quixote-0.6b1\server\medusa_http.py    Fri Jan 17
00:42:48 2003
+++ C:\Python22\Lib\site-packages\quixote\server\medusa_http.py    Fri
Jan 17 00:31:30 2003
@@ -15,4 +15,5 @@
 from quixote.http_request import HTTPRequest
 from quixote.publish import Publisher
+from quixote.errors import PublishError

 class QuixoteHandler:
@@ -52,4 +53,6 @@
                    'HTTP_COOKIE':msg.get('Cookie'),
                    'HTTP_REFERER':msg.get('Referer'),
+                   'ACCEPT_ENCODING':msg.get('Accept-encoding'),
+                   'HTTP_USER_AGENT':msg.get('user-agent'),
                    'PATH_INFO':request.uri,
                    'QUERY_STRING':query_string,
@@ -63,14 +66,17 @@
                    'SERVER_SOFTWARE':self.server_name,
                    }
-    for k,v in environ.items():
-        if v == None:
-        environ[k] = ''
+        for k,v in environ.items():
+            if v == None:
+                environ[k] = ''

         stdin = StringIO(data)
         qreq = HTTPRequest(stdin, environ)
         qreq.process_inputs()
-        output = self.publisher.process_request(qreq, environ)
+        try:
+            output = self.publisher.process_request(qreq, environ)
+        except PublishError, perr:
+            output = self.publisher.finish_interrupted_request(qreq, perr)
         if output:
-            qreq.response.set_body(output)
+            qreq.response.set_body(str(output))

         output_file = StringIO()


On another note, is there any interest in a composite Publisher design?
Either implementing a base Publisher and doing session management as a
mixin rather than a subclass; or implementing a ChainPublisher class
that could push a request through a succession of other publishers? Just
my two cents, but it felt it a bit funny to have to use a subclass to
get session management, it felt like a natural mixin opportunity.

The chain idea has been used in other app servers, I think Sun's Brazil
server did it that way, and some other that's escaped my memory. (In
that model, each sub-publisher had a chance to pre-process and
post-process each request, with the post-processing being done in
reverse order through the chain. Logging, exception handling, sessions,
etc. were implemented as post-processing on the up-stream publishers.)
Bear in mind that I'm very new to Quixote, so perhaps I'm not grokking
the the Publisher design yet.

Thanks, by the way! I really like what you've done with Quixote, and
look forward to using it in some real work, real soon!

-- Graham




reply