One great big bag of Plone problems

Assorted bugs, weirdness and some solutions.

Whenever I get a cryptic error from Plone (which is all too frequently), I google to see if anyone else has it. This is me paying back into the system.

Can't add type: 'NoneType has no attribute get'

After fiddling with the schema on a type, adding it then failed, with the informative traceback:

Traceback (innermost last): ... Module
Products.Amergin.content.phylogeny, line 6, in addPhylogeny Module
Products.BTreeFolder2.BTreeFolder2, line 446, in _setObject ... Module
Products.Archetypes.BaseContent, line 42, in manage_afterAdd ... Module
Products.ZCatalog.Catalog, line 277, in updateMetadata Module
Products.ZCatalog.Catalog, line 417, in recordify Module
Products.Archetypes.ExtensibleMetadata, line 314, in CreationDate
AttributeError: 'NoneType' object has no attribute 'get'

There's a lot more of it, but you get the idea. Looking at the source for the final error, you can see that the problem is that the new object has no field 'creationdate' and crashes out at that point. It took quite a while to find the answer but in my schema definition for the class I had mistakenly cut out the required base schema for an archetypes object:

_phylogeny_schema = Schema (( ...

instead of:

_phylogeny_schema = BaseSchema.copy() + Schema (( ...

Moral: as forbidding as it is, looking at the source can be a great help.

Rant: there's two problem with errors in Plone (1) they're far too easy to make and (2) they're far too cryptic. Ideally, Archetypes shouldn't even provide the option of creating an schema that's illegal, and the errors from such should have been caught earlier in the creation machinery rather than later. ExtensibleMetadata is 700 lines long, doesn't contain a single assert and only raises one exception.

Can't delete object because it is locked

One of my Products creates a lot of content programatically (i.e. without the user directly adding it). In the upgrade between 2.5 and 3.0, a strange thing started happening. Content created this way could not be deleted, giving a message like the title. It was as if the object hadn't properly left the portal factory, although it was being created in the same way as many other bits of code. But if you edited and saved the content, it was then "deletable".

The solution was simple: commit a transaction. This saves and unlocks the object:

import transaction transaction.commit()

Tip: There's some nice urls for reference Add content programmatically, Manipulating Plone objects programmatically, Create links with a script.

Rant: "Professional Plone development" has a single reference to transactions in its index, which points to a single page.

Abruptly truncating text

Symptom: When making an addition to one of the Infoglut pages, a scrap of text was cut and pasted out of another application (specifically an album title from iTunes). When the page was saved, the text appeared to be truncated around the point of insertion. Although this initially seemed to be a restructured text error, when the page was opened up for editing again, it was shown that the text was actually terminated at that point. All data beyond had been lost.

Solution: The behaviour is surprising, but the cause not. When the text was cut-and-pasted into a text editor, a stray invisible control character could be see at the point of truncation. Fortunately, by going back in the browser, I could fetch the original text from the cache, excise the problem character and repeat the edit to the correct form. It would seem likely that this wasn't iTunes fault, but due to whoever originally edited the album name.

Form misbehaviour

Symptom: Several products malfunctioned when their forms were submitted. For example, when a user created a guestbook entry in EasyGuestBook, at the stage where it should show a preview of the submitted text, Plone threw an error saying:

validateShowPreview contained an error

The control panel configlet for qPloneComments did a similar thing whenever a setting was changed. The only conmmon factor between these two seemed to be that they both used CMFFormController. No traceback was produced and both Products had previously been working fine.

Solution: it seems that the problem is to do with linefeeds. Both crashing scripts had DOS (CRLF) line-endings. How they got converted in unclear but presumably something in CMFFormController requires either native or Unix linefeeds. This is easily fixed by going to the skin directory and converting everything to Unix with:

dos2unix -d -o *

or similar. Caveat: this assumes you are using a Unix system, of course. If you're not, that's your problem.

pytz

Symptom: You know how it is. You want to try out some new Products or some cool stuff in a new version of Zope or Plone. So you install the latest Zope binaries, instatiate a site, start it up just to test it and get a freaky error message deep inside the timezone information that it doesn't understand the way you are calling timezones. Sure, happens all the time ...

Solution: I got around this mysterious bug by just hacking the call to the timezone module pytz. But belatedly there is an explanation and it doesn't involve Zope. Briefly, when matplotlib is installed, it also installs an old version of pytz. This can be cured by manually updating pytz in your distribution or in MPL. Let the user beware.

The valid images that aren't

Symptom: I was passed some artwork (in the form of JPEGs exported from Photoshop) to put up on a site. But if they were uploaded as an image, they didn't appear within the content type. They still appeared as the attached image under the edit tab, but couldn't be seen. They didn't even appear as a broken image icon. They could be uploaded straight to the ZMI, but again the content was present but the image wasn't visble. Loading as a skin element of a product produced similar results. The images appeared normal in Window's Image Viewer and OSX's Prefix and Graphics Converter. Resaving the images, or renaming, produced no chnage.

Solution: Comparing images that worked with those that didn't produced a clue. The problematic images had a CMYK color profile as well as some additional embedded fields. Saving the images wihtout this profile imnformation fixed the problem. Presumably the Python Imaging Library or Zope's internal image-handling code isn't savvy to part of this additional profile data.