osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Only a message at the highest exception


On 28Jun2019 12:17, Cecil Westerhof <Cecil at decebal.nl> wrote:
>Chris Angelico <rosuav at gmail.com> writes:
>> On Fri, Jun 28, 2019 at 7:33 PM Cecil Westerhof <Cecil at decebal.nl> wrote:
>>> I have a tkinter program where I have a function generate_report 
>>> which
>>> in a try block calls the function append_row. This function has also a
>>> try block. When they get an exception they give message. But when
>>> append_row has already given a message then generate_report should
>>> not. To implement this I use the following class:
>>>
>>>     class AlreadyHandledException(Exception):
>>>         pass
>>>
>>> Then in append_row I have:
>>>     except Exception as err:
>>>         messagebox.showerror(error_str,
>>>                              error_append + '\n\n\n\n' + str(err))
>>>         raise AlreadyHandledException()
>>>
>>> And in generate_report I have:
>>>     except Exception as err:
>>>         if type(err).__name__ != "AlreadyHandledException":
>>>             messagebox.showerror(error_str,
>>>                                  error_generate + '\n\n\n\n' + str(err))
>>>         progress.pack_forget()
>>>
>>> Is this an acceptable way, or should I do it differently?
>>
>> Well, first off, I would use two separate except clauses, rather than
>> a type check.
>
>You are completely right.
>
>> But are you able to just NOT catch the exception inside
>> append_row? Let it be handled at the top level only.
>
>I am giving different messages. I changed the top part to:
>    except AlreadyHandledException:
>        pass
>    except Exception as err:
>        messagebox.showerror(error_str, error_generate + '\n\n\n\n' + str(err))
>    progress.lower()

For contrast, another approach.

By catching AlreadyHandledException and just going "pass" you're 
effectively swalling that exception. For your purpose, that works.

However, in a since, why raise an exception you _know_ you're going to 
deliberately ignore?

What if you have append_row return a Boolean? True on success, False on 
failure but situation handled (i.e. append_row has shown an error, or 
whatever recovery you adopt). And keep the uncaught exceptions for the 
_unhandled_ situation. The "exceptional" situation.

Example:

  def append_row(...):
      ...
      try:
          ...stuff...
      except ExpectedExceptionHere as err:
          messagebox.showerror(....)
          ...maybe some cleanup...
          return False
      ...
      return True

Then your generate_report code goes:

    try:
        appended = append_row(....)
    except Exception as err:
        messagebox.showerror(....)
    else:
        if appended:
            hooray!
        else:
            unhappy, but continuing

avoiding a "do nothing" special except clause.

Cheers,
Cameron Simpson <cs at cskk.id.au>