About ConflictErrors

Hi,

I still lack some understanding about ConflictErrors, especially when they can possible happen and when to handle them in the application code.

I just found a code fragment in my code base as follows:

try:
    self.MailHost.send(email.as_string(), mto=recipient_address, mfrom="No-Reply@example.net")
except ConflictError:
    raise
except:
    pass

(email is an instance of MIMEMultipart and gets completely configured with strings - no method calls).

How (on earth) could there ever happen a ConflictError?

Afaik Zope retries requests three times anyway when there is a ConflictError.

So in which situation should I handle ConflictErrors in my Zope app directly?

Thanks in advance!

I don't see how MailHost.send() could cause a ConflictError

Well, I remember it was happening when sending newsletter with no mail queue enabled (with Products.Plonegazette or Products.EasyNewsletter or whatever).
The time delay required for sending the mail in realtime was so big that conflict error happened (some times because the operator got a time out and restarted the procedure).
After enabling the mail queue the submission was super fast and no conflict error happened again.

@jugmac00 try to see if self.MailHost.send(email.as_string(), mto=recipient_address, mfrom="No-Reply@example.net", immediate=False) works better for you.

At least immediate is a valid parameter in Plone's MailHost:

The piece of code you are looking at uses an idiom to ensure that the application does not handle ConflictError. As you are aware, it is very rarely a good idea to try to handle ConflictError (in the application). The code above wants to ignore exceptions, but not ConflictError.

Use the idiom above whenever you use a "bare except" in a ZODB context (it would be better if the ZODB would derive its ConflictError from BaseException (rather than Exception), but it does not do this).

2 Likes

Thanks for the replies, and especially @dieter for explaining this idiom. Now it makes so much more sense, why it was used. Let alone catching Exception would be rarely a good idea - at least in the contexts I found it.

Plone Foundation Code of Conduct