Le problème est extrèmement spécifique à l'exception, aussi doutés-je qu'il existe un traitement générique.
Voilà une solution simple et efficace… tant que rien ne change dans l'API de datetime :
import time, arrow, datetime
from datetime import datetime
def problem_origin(e):
for origin in ('month', 'day'):
if e.args[0].startswith(origin):
return origin
try:
goo = arrow.get(datetime(1985, 17, 4))
except ValueError as e:
print(problem_origin(e))
try:
goo = arrow.get(datetime(1985, 11, 34))
except ValueError as e:
print(problem_origin(e))
Sinon, je serais d'avis de prendre le problème à la racine :
import time, arrow, datetime
from datetime import datetime as datetime_system
def datetime_wrapper(func):
def problem_origin(e):
for origin in ('month', 'day'):
if e.args[0].startswith(origin):
return origin
def wrapper(year, month, day):
try:
ret = arrow.get(datetime_system(year, month, day))
except ValueError as e:
if problem_origin(e) == 'day':
raise ValueError("unexpected day value")
else: # month fucked up
raise ValueError("unexpected month value")
return ret
return wrapper
datetime = datetime_wrapper(datetime_system)
try:
goo = arrow.get(datetime(1985, 17, 4))
except ValueError as e:
print(e)
try:
goo = arrow.get(datetime(1985, 11, 34))
except ValueError as e:
print(e)
Dans ce cas, pas nécessairement besoin de lever une exception : le décorateur peut opérer des changements, appeler un logger,…
Il est aussi possible (peut-être même plus sûr) de tenter un truc comme ça pour la fonction problem_origin:
def problem_origin_from(year, month, day):
try:
return arrow.get(datetime_system(year, month, day))
except ValueError as e:
try:
month = 1
arrow.get(datetime_system(year, month, day))
print("unexpected month value")
except ValueError as e:
print("unexpected day value")
Le principe : plutôt d'extrapoler soit même les conditions de succès de datetime, on va modifier un par un les arguments de manière à éliminer l'erreur.
Dans ces conditions, c'est moche mais on évite d'avoir à recoder soit même un ersatz de vérification de date.