I want to make sure a method is called if any exception is raised. In this situation, is it ok (good/bad practices or may lead to unexpected consequences) to try/except any Exception? Here's an example of what's on my mind using a decorator:
# implementation
import sys
import traceback
class AmazingClass:
  def __init__(self, arg=None):
    self.__att = arg
  @property
  def att(self, ):
    return self.__att
  def make_sure_it_quits(method):
    def inner(self, *args, **kwargs):
      try:
        return method(self, *args, **kwargs)
      except Exception as err:
        print(err, "- This was caught because it couldn't be foreseen.")
        traceback.print_exc()
        print("\nQuitting what is suppose to be quited...")
        self.quit()
    return inner
  @make_sure_it_quits
  def this_may_raise_errors(self, arg):
    try:
      self.__att += arg
    except TypeError as err:
      print("This I can handle! Cleaning and exiting...")
      self.quit()
      # sys.exit(1)  # exit, if it's the case
  def quit(self, ):
    self.__arg = None
    print("Everything is very clean now!")
# examples
def no_errors():
  obj = AmazingClass("test")
  obj.this_may_raise_errors("_01")
  print(obj.att)
def with_error_01():
  obj = AmazingClass("test")
  obj.this_may_raise_erros(1)
  print(obj.att)
def with_error_02():
  obj = AmazingClass("test")
  obj.this_may_raise_errors()
  print(obj.att)
# main
if __name__ == '__main__':
  no_errors()
  with_error_01()
  with_error_02()
In this case, with_error_01 represents situations I know in advance that can happen, while with_error_02 is an unexpected use of the class.
In both cases, the use of traceback shows what and where went wrong. Also, the method quit must always be called in case of any error.
