[Twisted-web] freeform and adbapi

Tommi Virtanen tv at twistedmatrix.com
Sun Apr 17 22:58:18 MDT 2005


Stephan Cieszynski wrote:
> Sorry, but the following description lead me to use a deferred:
> 
> formless/iformless.py:
>     def coerce(self, val, configurable):
>         """Coerce the input 'val' from a string into a value suitable
>         for the type described by the implementor. If coercion fails,
>         coerce should raise InputError with a suitable error message
>         to be shown to the user. 'configurable' is the configurable object
>         in whose context the coercion is taking place.
> 
>         May return a Deferred.
> -----------------------^
>         """

That's what the documents say, but sadly not what the code always does.
It may even work in some cases, but definitely not in many cases.

.coerce() is called from .process(), which returns the value
directly through, and only does exception handling for immediately
raised exceptions:

         try:
             result[binding.name] = iformless.IInputProcessor(
                 binding.typedValue).process(context, boundTo,
                 data.get(binding.name, ['']))
         except formless.InputError, e:
             result[binding.name] = data.get(binding.name, [''])
             raise formless.ValidateError({binding.name: e.reason},
                                          e.reason, result)
...
         return result

A Deferred returning an errback in the above will go unnoticed by that
code.

> Your example not working:
> First, if 'foo' is a deferred the callback isn't fired at this time and 
> validating isn't possible.

"foo" is a _function_. It cannot be a Deferred. Did you mean if "foo"
_returns_ a Deferred, that is "if 'foo' is deferred", without "a"?
I still can't parse that sentence.

 > Second, raising an exception in a autocallable like this
> def foo(self, ctx, bar):
>     def _cb(r):
>         if not valid(r):
>             raise annotate.ValidateError(...)
> 
>     bar.addCallback(_cb)
> 
> take no effect at rendering time and the slot('error') isn't filled with 
> our errormessage.

bar.addCallback? If bar is Deferred, nevow should not call that function
until it has a result for the Deferred. Though I wouldn't be surprised
to see more bugs in this area..

Callers not seeing the raise ValidateError is only logical, because you
raise it in a callback of a Deferred nothing waits on. That's like 
returning a value from function, but no one using or storing that value
in any way. "return bar" may change things there.



More information about the Twisted-web mailing list