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

_______________________________________________
Python mailing list
Python@lists.python.it
https://lists.python.it/mailman/listinfo/python

Rispondere a