[Web-SIG] Possible specs

Ian Bicking ianb at colorstudy.com
Mon Nov 13 21:51:07 CET 2006


Luke Arno wrote:
>> >> >>      * Some systems prefer that unexpected exceptions bubble up, 
>> like
>> >> >> test frameworks. A key could define this case (modelled on
>> >> >> paste.throw_errors) and thus disable exception catchers.
>> >> >
>> >> > -1 I don't need it. Too abstract.
>> >> >
>> >> > Usually, you just have one error handling
>> >> > middleware on the outside of the rest, no?
>> >>
>> >> Sometimes there's multiple pieces of middleware.  For instance, I 
>> might
>> >> have one on the outside, with another one in a subapplication 
>> (which is
>> >> independently deployable, so needs some kind of wrapper).  Also it is
>> >> needed to avoid catching errors when running tests, where you want the
>> >> exception to go up all the way to your test runner (which might have a
>> >> debugger or special traceback formatter).
>> >
>> > This is probably just not relevant to my development
>> > style. Or maybe I just don't get it.
>>
>> Well, the general pattern is:
>>
>> def error_catcher(app):
>>      def replacement_app(environ, start_response):
>>          if environ.get('paste.throw_errors'):
>>              return app(environ, start_response)
>>          try:
>>              return app(environ, start_response)
>>          except:
>>              # handle and report on error
>>      return replacement_app
>>
>> In a testing environment I always want errors to bubble up, I don't want
>> a 500 response if it can be helped; so in paste.fixture.TestApp I always
>> set this.
>>
>> It's not a big deal, but it's fairly simple to explain and handle.  Low
>> hanging fruit.
> 
> I just put such things in a usually-outermost wrapping
> context and test without it. I don't catch unexpected
> exceptions at anyplace else in the stack so I guess
> that is why this doesn't make sense to me.

Sometimes it is hard to pull apart stacks, and sometimes you want to 
embed a stack that already includes an exception handler.  For instance, 
Zope includes an option exactly like this.  I think Zope 3 actually uses 
something like 'wsgi.throwErrors' for this same idea, which they came up 
with independently.

Anyway, it's pretty obvious how it works and it's really easy to support.

One of the other places where it is useful is to wrap an application 
with a different error catcher (like paste.evalexception) and not have 
to worry about unpacking the enclosed application to disable its 
exception handler.  I've done this several times when debugging 
application deployment issues.

[re: paste deploy]
>> It gives you a consistent way to configure WSGI stacks, from a config
>> file, database, or whatever.
> 
> That much I do get. It seems clever but I have never
> needed to do it. Outside of Paste and Paste users I always
> see folks just building stacks in good old Python.

How do non-developers ultimately deploy the application?  How do they 
construct stacks of software to make a web site?  I suspect (barring 
this sort of interface) that it's done in an ad hoc manner, which will 
seem fine so long as applications are one-off and/or deployed by the 
programmer.

Note that I don't encourage people to use configuration to put together 
an application's stack; you should do that in Python code, and you may 
or may not use this interface to do so.  But for putting together a 
single site, or for deploying an application, I don't think relying on 
Python code is a good idea.  (Note that the interface doesn't *keep* you 
from using Python code, it just makes it possible to build other tools.)

>> I'm not a big fan of forwarding and using exceptions to unwrap the
>> middleware.  But including content is much simpler.  I think it can be
>> as simple as:
>>
>> def middleware(app):
>>      def replacement(environ, start_response):
>>          anchors = environ.setdefault(
>>              'x-wsgiorg.app_anchors', {})
>>          anchors[environ['SCRIPT_NAME']] = (app, environ.copy())
>>          return app(environ, start_response)
>>      return replacement
>>
>> This gives you the app and an indication of what the environ looks like
>> when the app is typically reached.  From here you can implement
>> recursive calls fairly easily.
>>
>> Whether there should be support for multiple anchors, I'm not sure.  I
>> think it could be argued that the closest anchor is best to use, but the
>> furthest one offers the most URI space (supposing there are multiple
>> pieces of middleware like this in a stack).
> 
> Fancy. Confusing. Only works under the right
> conditions, no? I think this is cool experimentation
> but I just don't think it is a good candidate for
> standardization.

Well, tools that could do recursive calls have to look for *something*. 
  And something has to be put into the stack to make this possible.  I'd 
like to write tools that do this that don't require a Pasty stack; 
without any particular standard there's no way to do that.

In terms of its applicability and functionality, it works fine.  It's a 
kind of functionality that is fairly common in other stacks, including 
Apache itself.

Of course consuming this key is something a library routine should do, 
it's not easy to consume by hand.  What I'm proposing is the minimum 
thing necessary to make the library routine feasible.  Note if you do it 
statically (getting a hook to the original app without the environ, and 
without middleware) you will have to give information like hosts and 
paths that may or may not match up with the actual requests that come 
in.  As a result I think it's much better to do this as middleware.


-- 
Ian Bicking | ianb at colorstudy.com | http://blog.ianbicking.org


More information about the Web-SIG mailing list