[Mailman-Developers] Translating notifications raised by mailman-core in postorius

Barry Warsaw barry at list.org
Tue May 17 10:40:57 EDT 2016

On May 17, 2016, at 11:15 AM, Simon Hanna wrote:

>Theoretically the core could translate the messages before passing them
>to postorius. This would require core to know about the language it
>should translate to. I don't think this is a very good approach because
>we would have to make sure we offer the same languages for core and
>postorius and I'm not sure how we would pass the languages to core...

Probably Accept-Language could be used to specify that, but I (think I) agree
it's not the right approach.  My only hesitation is to remember that Postorius
isn't technically the only web front-end that could be connected to the core.
If some homegrown ui also wanted translations, it's not clear how much they
could leverage of existing work if all the translations lived in Postorius.

>I propose core to return an error code with each request. That way
>postorius can add strings for all the errors that it cares about and
>translate them accordingly. This would require an api change. Since 3.1
>would change the api anyway, it would be nice to include the changes there.

If we're going to return an application-specific error code (in addition to
the HTTP response code we already return), then I think it means we'll be
returning a JSON structure even on error conditions.  Right now, JSON is only
returned on success, and strings are returned on errors.

If we say in API 3.1 that JSON is always returned, then we have some
additional options.  What makes the most sense to me would be to always return
a dictionary with some well-defined keys.  That at least gives us a chance to
evolve the API probably without having to rev the API version in the future.

One problem with returning Mailman-specific error codes is that we'll need *a
lot* of them.  Essentially one for every error condition in the REST API.
I've always found such arrangements a nightmare to maintain and debug.  Error
codes have no obvious meaning so the mapping of code to meaning always has to
be looked up.  We could segment the error space so that there's some semantic
equivalence (e.g. 01xx means a list-specific error, 02xx means a
membership-specific error, etc.) but there's always some twisting that goes on
the keep those up-to-date and meaningful within the semantics we give them.

And it's still not enough, because as you point out, there is always going to
be variable data that has to be associated with the error.  A good example is
when a mailing list is created within a nonexistent domain.  The error reason
is something like:

    'Domain does not exist: example.net'

which gets interpolated on the server side.  So obviously an error code like
0135 won't help because you could only translate that to 'Domain does not
exist' without also knowing the name of the domain that failed.

So now we also have to include some variable data in the JSON response.  Which
leads me to think, why do we need error codes when we already have a format
perfectly suited to the cause, and which we already use internally for other
translatable contexts, i.e. PEP 292 strings ($-strings).

Thus, our error responses could be something like:

    'reason': 'Domain does not exist: example.net',
    'template': 'Domain does not exist: $domain',
    'data': {
        'domain': 'example.net',

'reason' would always be the interpolated English (i.e. source) string.
'template', and 'data' should be obvious.  We need a separate namespace for
the interpolation data.

A front-end could just use the English reason, or it could translate the
template and interpolate the data dictionary into it.

Making this change would be a lot of work, but it could be done in several

One branch would provide the infrastructure to return JSON error responses.
These would only be done for API 3.1, and possibly you'd also want to check
the Accept header to make sure the client is prepared to accept JSON.  Then
all of the error reporting call sites would have to be changed to pass in the
template and data dictionaries, with the helpers doing the interpolation for
'reason' and the setting up of the response correctly.  Then tests and
documentation. :)

If you like the general approach we can hash out implementation details.
Given however that Pycon is near and I *really* want to get 3.1 out during
Pycon and there are already at least two big features that still have to be
added (unsubscription workflow and template support), it might be better to
defer this to core 3.2 and API 3.2.  That way, we can get it right without
rushing it in.


More information about the Mailman-Developers mailing list