Contexte ====== La plupart des librairies nuiton utilisent i18n pour les messages des exceptions. Certaines d'entre elles sont intéressantes d'un point de vue fonctionnelle et les messages pourraient directement être retournés à l'utilisateur. Par exemple lors d'un import CSV (nuiton-csv), les messages d'erreurs définissent le numéro de ligne, le type d'erreur, etc... Problématique ========= Les messages d'exceptions sont directement traduit avec i18n avec l'utilisation de la méthode _(). Cependant dans un contexte web, la locale dynamique modifiée depuis l'interface, ne change pas l'état d'I18n qui garde sa locale par défaut à l'initialisation. Comment récupérer alors la clé i18n ou trouver un système permettant de traduire l'exception en fonction de la locale du contexte web ? Solution 1 (la plus simple) ================ L'API de la JDK propose une méthode getLocalizedMessage() mais la locale n'est stipulé nul part. Il faudrait potentiellement la pousser soit via constructeur (trop intrusif), soit via getter/setter (plus souple, car la locale peut être mise au moment du catch par exemple). Ainsi la méthode getLocalizedMessage() renverrais une traduction localisé (si la locale est mise) en fonction des paramètres de l'exception. Quelque chose comme : @Override public String getLocalizedMessage() { String result; if (locale == null) { result = getMessage(); } else { result = l_(locale, i18nKey, getMessageArgs()); } return result; } Le paramètre i18nKey pourrait être le message de l'exception en utilisant n_("i18n.key") au moment de l'instanciation. Les "messageArgs" dépendent de l'exception. Plus ou moins dynamique suivant les besoins. Variante: ------------ Quitte à avoir une api avec les getter/setter sur la Locale, autant ajouter directement une méthode getLocalizedMessage(Locale locale). => Cela implique un ajout et une gestion de la locale dans toutes les exceptions que nous utilisons dans les librairies, ou à minima les plus pertinentes comme la validation ou l'import/export CSV. Solution 2 (la moins coûteuse en refactoring) ============================ Avoir une option pour traduire en utilisant un ThreadLocal permettant de stocker la locale. Ainsi toutes les méthodes _() seront contextualisés par rapport à ce ThreadLocal. Solution 3 (l'autre) =========== Laisser le loisir de traduire le message à l'interface cliente. Dans ce cas toutes les instanciations d'exception devront utiliser n_() plutôt que _() pour garder la clé i18n en tant que message. Libre à l'interface cliente de le traduire ou non. Les traductions des librairies seront toujours présentes grâce aux bundles. Variante (plus compliqué): ----------------------------------- Une autre idée serait de garder la clé i18n mais aussi ses paramètres. Je me suis toujours demandé l'intérêt d'avoir n_("i18n.key", arg1, arg2) alors que finalement arg1 et arg2 ne seront jamais gardé ni utilisé (a moins que je me trompe ?). On pourrait avoir une autre méthode qui sérialise les paramètres (vu que de toute façon on veut des string). s_("i18n.key", arg1, arg2) = "i18n.key|toto|18" qui serait le message de l'exception. Ensuite _() doit être capable d'interpréter ce parsing avec le séparateur | (ou n'importe quel caractère qui ferait l'affaire). => Les solutions 3 et 4 posent le problème du logging ou des catch automatique des framework. En effet, la méthode getMessage() sera généralement appelé sur les stackTrace, mais ici on aura pas de traduction, à moins encore une fois de surchargé la méthode getMessage() de toutes les exceptions (pour appeler _() ) et d'ajouter une autre méthode getOriginalMessage() pour avoir la clé sérialisé. Conclusion ======= Cela reste une problématique qui a ses limites. A t-on la réelle nécessité de devoir traduire tous les messages d'exceptions ? Ne faudrait-il pas tout laisser en anglais et laisser faire les interfaces ? De mon point de vue, je ne sais pas encore quelle est la meilleure solution. Mais je trouve dommage d'avoir toute la gestion i18n de faites dans les messages d'exceptions alors qu'elle est inutilisable dans un contexte web...