Threaded Exceptions in Python

2

I am in doubt in a situation not so common but that I have seen some developers use that is the case of concatenation of exceptions.

I read the Python documentation about them but it was not as clear as Python acts behind the wipes in order to silence the first exception. If you can give me an example code explained would be great.

Example:

Code:

try:
    1 / 0
except ZeroDivisionError:
    print("Exception: ZeroDivisionError")
    raise Exception from None
    
asked by anonymous 04.04.2018 / 18:10

1 answer

1

It does not have much mystery there: the "silencing" of an exception within an exception is part of the way Python is done.

Always have to keep in mind that unlike compiled code, where an error in the program will put everything running in an invalid state in Python, program execution is under Python's runtime control. An exception in executing Python code is an object, like any other object - with its attributes and etc ... what is different is that when an exeception occurs (either because it acotneceu same, or because of a command raise ), the interpreter for executing the Python code the point it is in, and returning all the functions (technically, goes to the previous% execution%) until it finds an "except" block that matches the exception that occurred ( if the try / except is at the same point where the exception occurred, it may not return from any function). At the point where the exception is, Python associates the exception object with a local variable (which is in frames ), and starts executing the code of block except normally: at this point, the prog is consistent, and " under control ", not in an error condition. So much so that it is perfectly valid to simply put a except inside a except clause, to ignore an error (if we know it is a kind of temporary error that can happen from time to time and does not disrupt the operation of the program). >

Now, if there is a pass within raise from , Python simply creates a new exception object, copies some data from the original exception object to the new exception, and restarts the "going back" task in code until you find a corresponding exception. In the case of except you're explicitly saying not to get data from the original exe - would be the same as raise ...from None without raise Exception .

Language does this. Now why do programmers put this in code? This may be your own doubt, and it is a question of the staff who expressed themselves in the comments.

Let's take the example of a web application running within a framework: the functions of the web application itself, such as views, are called when there is a web request that the framework directs to itself - but they are not the "The framework generally receives data about the web request," dissects the url ", decides which view is called, arranges one or more internal objects (for example" request "), and then calls the application's view. This is all Python code inside the framework. The Framework will generally call the view for the user inside a "try: / except" block; Otherwise, any exception in the view would stop the server process from the framework (ie, it gave error to serve a page, the whole server to -not what you want in general - you want the server to continue serving other pages to the other users and even to the one who found the error).

If this try / except block of the framework intercepts an exception from which it knows nothing, it will generate a "500" HTTP error. : That is, it will look at the settings of your app, or use the default settings of the proper framework, and return to the browser the html that is set to when there is an 'error 500.' It turns out that the framework in general will have exceptions from it even though your application may use it to indicate that it was not a "500" error, but a "404" or "403" error (page not found or access denied), or any other http error (and both the framework and your application may want to show specific pages in this case).

So, if within the code of your view, you are going to access the database and did not find the object searched for - or obtained some other error, the search can generate a from (if you query the database, expects to have a result and has zero, for example) - if you leave the IndexError "up" to the framework code, you will get a 500 error. But in the code of the view, you, in writing the code, know that if a "IndexError" at that point, is why the user, or other object was not found in the database - and may want to show an "error404" in the browser -

So, it's a natural pattern something like

@view("/")
def minha_view(request):
    try:
        user = get_from_users(request.user)
    except IndexError as error:
        raise HTTPError404 from error

    # aqui continua o código para uma requisição bem sucedida
    ....

(In this case, "HTTPError404" would be an exception defined in the framework).

    
05.04.2018 / 03:40