[Twisted-Python] Clarification on returning exceptions via Perspective Broker
Hi all, I'm using the Perspective Broker to run functions on various remote servers, and trying to pass exceptions raised in the remote functions back to the client. My exceptions subclass pb.Error, which means tracebacks are suppressed on the server and errbacks triggered on the client, exactly as I'd hoped. What I'm confused about though, is why the serialization/deserialization process reduces my nice structured exception into a mere string. Isn't PB's raison d'être to allow you to send fully formed Python classes over the wire? I'm not 100% convinced that I've not misinterpreted something, but assuming that pb.Error subclasses are indeed reduced string representations, I'd appreciate some insight into why PB behaves this way. I have experimented with returning a standard Exception subclass to the client, but what it receives is "Unpersistable ... instance deemed insecure", which I guess has something to do with the design rationale, but I don't know enough to understand why. Finally, is there a standard workaround to this that allows structured data to be returned as or along with the exception, rather than having to generate structured text as the string representation and then rebuild the object at the other end? Many thanks, Matt.
On Thu, Aug 13, 2009 at 10:32 AM, Matt Bennett
My exceptions subclass pb.Error, which means tracebacks are suppressed on the server and errbacks triggered on the client, exactly as I'd hoped. What I'm confused about though, is why the serialization/deserialization process reduces my nice structured exception into a mere string. Isn't PB's raison d'être to allow you to send fully formed Python classes over the wire?
It's been a while since I worked with this, but I believe the rationale goes something like this: the most common type of error in PB is a serialization or deserialization error. You sent too much, you didn't send enough, your jellier doesn't quite match your unjellier, there's a version skew problem. If exceptions contained structured data, there's a risk that that data will *also* have a serialization error; or, worse yet, attempt to include the problematic data which caused the error in the first place. So it's generally not a good idea to work around this, because you can easily cause a mutually recursive loop where reporting the error causes another error that needs to be reported. That said, based on memory and a brief read-through of the code, PB does support returning structured exceptions; you can't just return a normal Exception subclass, you need to register it as serializable the same way you would any other object, and it needs to subclass Jellyable (for example by subclassing Copyable). (I could be wrong, but I believe that is the intent.)
Thank you for the explanation Glyph. Having spent some time
understanding the mechanics of the jellying process, I can see why
things are implemented as they are.
In my path to understanding I came across pb.CopyableFailure, which is
where the state to be passed through PB is extracted from an
Exception. For future reference, I believe patching CopyableFailure to
allow certain parts of the exception to persist would be the quickest,
dirtiest workaround. But for the good reasons outlined I'm not going
to ;-)
Thanks again for the prompt feedback.
Matt.
On Thu, Aug 13, 2009 at 8:50 PM, Glyph Lefkowitz
On Thu, Aug 13, 2009 at 10:32 AM, Matt Bennett
wrote: My exceptions subclass pb.Error, which means tracebacks are suppressed on the server and errbacks triggered on the client, exactly as I'd hoped. What I'm confused about though, is why the serialization/deserialization process reduces my nice structured exception into a mere string. Isn't PB's raison d'être to allow you to send fully formed Python classes over the wire?
It's been a while since I worked with this, but I believe the rationale goes something like this:
the most common type of error in PB is a serialization or deserialization error. You sent too much, you didn't send enough, your jellier doesn't quite match your unjellier, there's a version skew problem.
If exceptions contained structured data, there's a risk that that data will also have a serialization error; or, worse yet, attempt to include the problematic data which caused the error in the first place. So it's generally not a good idea to work around this, because you can easily cause a mutually recursive loop where reporting the error causes another error that needs to be reported.
That said, based on memory and a brief read-through of the code, PB does support returning structured exceptions; you can't just return a normal Exception subclass, you need to register it as serializable the same way you would any other object, and it needs to subclass Jellyable (for example by subclassing Copyable).
(I could be wrong, but I believe that is the intent.)
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
participants (2)
-
Glyph Lefkowitz
-
Matt Bennett