Hi Chris,
cewing wrote:
Hello all,
I've got a content type that represents a certain type of data file, a
VR2File. When a VR2File is added to the portal, I've been using a
registered handler for IObjectInitializedEvent to parse the data from the
uploaded file and insert the results into an external relational database.
Have you looked at ContentMirror? It does this kind of thing. If nothing
else, you should be able to see how it deals with this kind of thing.
Up until now, when an error was raised in the parser code, I've been
allowing it to bubble up and abort the zope transaction, so that neither the
VR2File object, nor the rows in the external database get preserved. This
works functionally, but has a major drawback.
The problem is that when the parsing of a VR2File fails, my users are
confronted with an unfriendly error message (the standard 'call your
administrator with this code' message). In certain cases I would prefer it
if the creation of the VR2File object were aborted and the user were
returned to the Edit template, as if a validator on the form had failed.
Can you maybe create a validator (you can register validators as
subscription adapters or set them on your AT class) that means your code
never tries to save unless it actually has a valid file. I think that's
the preferred approach here.
I've been snooping around in Archetypes, trying to figure out how plone's
built-in types handle this sort of thing, and I've discovered the
plone_utils.addPortalMessage() method.
In code, we tend to do:
from Products.statusmessages.interfaces import IStatusMessage
IStatusMessage(request).addMessage('some message', type='error')
This works a neat trick to get my
human readable strings into the portal status system. But if I re-raise my
parser error, they still end up at the default error message template.
Right. In general exceptions shouldn't bubble up to the user at all. If
an exception is uncaught, it's a fatal, in-your-face kind of error.
Worse yet, if I don't re-raise the parser error, the plone-bound VR2File
object is created, but none of the data parsed ends up in the external
database.
It presumably just aborts before it gets to that point because you
swallowed the error, but didn't abort the transaction.
By the way, it's possible to present a custom view as a view onto an
exception. See FiveException and plone.app.linkintegrity. I still think
I'd use a validator, though.
I am beginning to suspect that the post-creation event handler is _not_ the
right place to have located my parser code. I would like to use parser
errors to work similarly to validation errors in a standard AT content type.
That is to say, I'd like them to abort the creation of the VR2File object
and return the user to the edit page, with a portal status message that
tells them what went wrong.
Indeed. :) I would at least do validation here. It's not necessarily a
bad idea to to the serialisation to the RDBMS in the event handler still.
Is this possible from a handler of IObjectInitializedEvent?
No. This is too late, as you've discovered. The validation phase is
already over.
If not, what is
a better hook upon which to hang my parsing code. I'm a bit stumped about
where I might inject that process in the standard AT form processing and
object creation code.
Martin
--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book
_______________________________________________
Product-Developers mailing list
[email protected]
http://lists.plone.org/mailman/listinfo/product-developers