How to handle exceptions properly in a pythonic way?

zljubisic at gmail.com zljubisic at gmail.com
Wed Nov 4 23:11:38 EST 2015


On Monday, 2 November 2015 21:59:45 UTC+1, Ian  wrote:


> I'm having a hard time understanding what question you're asking. 

:)
I am really having a hard time to explain the problem as English is not my first language.

> You
> have a lot of discussion about where to handle exceptions, 

That's right. I am not sure where to handle exceptions and at the same time to have the code clean as possible.

For example John from the previous post suggested raising exceptions in the get_html procedure. That would mean that I should put every call of get_html function to the try/except block.

In this particular example, I would like just to know whether I managed to get_html or not.
In case I am experiencing some problems inside of the get_html function I could maybe retry several times, but this function should return the html or inform the caller that it is unable to get the html. For caller, the reason why get_html function couldn't get the html is not important.

For now, I am thinking that maybe I should use an approach in which I will have except block in get_html that will be responsible for several exceptions, something like this:

def get_html(url):

    try:
        wpage = requests.get(url)
    except ConnectionError, exception_a, exceptionb...:
        flog('warning', 'ConnectionError exception', log_except=True)
        raise NoHtml

    return

In that way the caller can put get_html function in try/except block but just paying an attention to the NoHtml exception which is much clearer than to have except ConnectionError
except exception_a
except exceptionb...: 
in every call of the get_html.

> but the
> examples that you show are of logging the the exception and re-raising
> it, which is a good practice but distinct from handling the exception.

I mentioned logging in get_html because I don't know what else I should do with an exception in get_html function.

> Then you seem to be asking about the practice of returning None as an
> alternative to propagating the exception, but the example you show
> only returns None in a case where no exception was raised in the first
> place.

I returned None based of the wpage.status_code == requests.codes.ok.
I assume that if this condition is true, everything went well.
Otherwise, I could forget to put some explicit exceptions in the except block so try block will pass even if certain exception has happened.
I read that catching all exception with except Exception as e: is not a good option. 

> None is arguably reasonable to return when it makes sense as a
> non-exceptional value in the context. For example, if you're looking
> up a policy that may or may not exist, then your get_policy function
> might return None to indicate no value. If get_policy fails because of
> an RPC timeout however, then it needs to raise an exception rather
> than possibly incorrectly returning "no policy".

If I understood correctly, in my case I could ask for getting the html from non existent web page or I can have communication (network) problem.
In any of these two cases if I return None I will newer know that web page doesn't exist. Good point.

> In comparison, if you're returning something that should always have a
> value, then you should never return None. In such a case, None would
> indicate that something went wrong, but it lacks any information about
> *what* went wrong. An exception, on the other hand, is ideal for
> carrying that sort of information. Returning None in such a scenario
> is also risky in that the caller may not be expecting None and may try
> to treat it as a normal value. In some cases this may even appear to
> work until something breaks in a completely different part of the
> code.

So my get_html function should never return None in that case.
 
> In the example given, the case where None is returned is clearly an
> exceptional case (non-success) even though no exception was raised by
> requests.get. You should raise an exception there instead of returning
> None to allow the caller better control over the situation.

I am kind of getting the philosophy of exceptions but I still have some dilemmas as you could see above. 

Thank you very much for your comments.

Regards.



More information about the Python-list mailing list