[Python] Info su cancellazione traceback
Marco Giusti
marco.giusti a posteo.de
Sab 19 Nov 2022 10:47:42 CET
On 19.11.2022 08:45, Matteo Boscolo wrote:
> Buongiorno a tutti,
>
> vorrei cancellare il traceback di python e mostrare solo il mio raise,
> questa cosa mi serve per evitare che lo stack dell'errore venga visto
> in console.
>
> ho provato con questo decoratore
>
> def avoid_traceback(message=''):
> ''' call a function a number of times '''
> def decorate(fn):
> @wraps(fn)
> def wrapper(*args, **kwargs):
> try:
> result = fn(*args, **kwargs)
> except Exception as ex:
> if message:
> raise Exception(message)
> raise Exception("Error on method %s" % fn.__name__)
> return result
> return wrapper
> return decorate
>
>
> che funziona, ma il traceback resta attivo, nel senso che se metto
>
> traceback.print_exc()
>
> mi vedo tutto lo stack dell'errore:
>
> Traceback (most recent call last):
> File "/media/OneTDisk/workspace/test.py", line 133, in wrapper
> result = fn(*args, **kwargs)
> File "/media/OneTDisk/workspace/test.py", line 218, in rise
> raise Exception("rise")
> Exception: rise
>
>
> potete provare con questo esempietto qua:
>
> class A(object):
> def __init__(self):
> pass
>
> @avoid_traceback("errore generico")#
> def rise1(self):
> return self.rise()
>
> @avoid_traceback("errore generico")#
> def rise(self):
> raise Exception("rise")
> a=A()
> a.rise1()
> traceback.print_exc()
>
> ho trovato in rete
>
> https://www.programcreek.com/python/example/119512/traceback.clear_frames
>
> ma sembra che non funzioni..
>
> qualche idea ?
Ciao Matteo,
vorrei premettere che non trovo sia una buona idea nascondere
informazioni quando si ha a che fare con delle eccezioni, anzi, piu'
informazioni ci sono e meglio e'. Comunque, usa il costrutto
raise exception from None
Quando lanci un'eccezione al momento in cui ne stai gia' gestendo
un'altra, le due eccezioni sono concatenate in due punti: __context__ e
__cause__. Il primo attributo e' settato automaticamente e per
sovrascriverlo hai bisogno di un ulteriore blocco try/except. Non farlo,
perche' per visualizzare il traceback e' usato __suppress_context__.
Se il valore e' False, allora viene visualizzato __cause__ o
__context__, se il valore e' True, allora la precedente eccezione non e'
visualizzata. Usando "raise ... from None: ottieni gia' quello
che desideri: __cause__ e' settato to None e __suppress_context__ e'
settato to True.
Ecco qualche esempio usando sempre questo codice e usando il decoratore
"avoid_traceback" solo sul metodo "rise1".
a = A()
try:
a.rise1()
except Exception as exc:
print(f"exc.__cause__: {exc.__cause__}")
print(f"exc.__suppress_context__: {exc.__suppress_context__}")
print(f"exc.__context__: {exc.__context__}")
raise
traceback.print_exc()
Esempio 1, lasciando il decoratore invariato:
$ python3 hide_traceback.py
exc.__cause__: None
exc.__suppress_context__: False
exc.__context__: rise
Traceback (most recent call last):
File "/home/marco/hide_traceback.py", line 11, in wrapper
result = fn(*args, **kwargs)
File "/home/marco/hide_traceback.py", line 27, in rise1
return self.rise()
File "/home/marco/hide_traceback.py", line 30, in rise
raise Exception("rise")
Exception: rise
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/marco/hide_traceback.py", line 35, in <module>
a.rise1()
File "/home/marco/hide_traceback.py", line 14, in wrapper
raise Exception(message)
Exception: errore generico
Esempio 2, usando raise ... from None
$ python3 hide_traceback.py
exc.__cause__: None
exc.__suppress_context__: True
exc.__context__: rise
Traceback (most recent call last):
File "/home/marco/hide_traceback.py", line 35, in <module>
a.rise1()
File "/home/marco/hide_traceback.py", line 14, in wrapper
raise Exception(message) from None
Exception: errore generico
Esempio 3, usando un ulteriore blocco try/catch
...
try:
try:
result = fn(*args, **kwargs)
except Exception as ex:
if message:
raise Exception(message) from None
raise Exception("Error on method %s" % fn.__name__) from
None
except Exception as exc:
exc.__context__ = None
raise exc
$ python3 hide_traceback.py
exc.__cause__: None
exc.__suppress_context__: True
exc.__context__: None
Traceback (most recent call last):
File "/home/marco/hide_traceback.py", line 39, in <module>
a.rise1()
File "/home/marco/hide_traceback.py", line 19, in wrapper
raise exc
File "/home/marco/hide_traceback.py", line 15, in wrapper
raise Exception(message) from None
Exception: errore generico
Maggiori informazioni sulla lista
Python