Show Catch More Specific Exceptions FirstRemember, your
When we tried to divide by zero, we
inadvertently raised a ZeroDivisionError. However, because ZeroDivisionError is a subclass of ArithmeticError, and Don’t Catch ExceptionIt’s bad form to catch the general Definitely don’t catch BaseExceptionCatching A little Python knowledge everyday!If you are doing Python codings, you must have used exceptions, because it is everywhere in the language. For example, when you press
In Python, exception handling has two parts: “catch” and “throw”. “Catch” refers to the use of Precise Exception CatchSometimes people think, “exceptions are a bad thing, and a good program should catch all exceptions and make everything run smoothly”. The code written with the idea will usually contains a large section of ambiguous exception capture logic. For example: import requests The And here are two steps that are prone to error: It seems simple and easy to understand, right? However if you try to run the script above. You will find that the above code cannot be executed successfully. And you will also find that no matter how you modify the value of the URL and the target file, the program will still report the error “save failed: unable to…” . why? The problem lies in this huge block of But due to the ambiguous exception catch that the error that should have been thrown due to the wrong method name The purpose of exception catching is not to catch as many exceptions as possible. It try to catch the most accurate exception. Then such a problem will not happen at all, and accurate capture includes:
Therefore, with the new purpose, let’s modify out code to: import re This time, it will throw the right exception: AttributeError: 're.Match' object has no attribute 'grop'. Did you mean: 'group'? Only Throw Exceptions for Current LevelLet’s take a look at the following code: def process_image(...): In the above code snippet, when developer first time wrote this function, it was under the use cause of processing user uploaded images, therefore when an image can not be opened, it throws an What if couple of month later, we need to reuse this The right way to fix this is to modify the original class ImageOpenError(Exception): Then in the upper level, you can catch and re-throw a different but more meaningful error: def process_existing_images(): In addition to avoiding throwing exceptions higher than the current abstraction level, we should also avoid leaking exceptions lower than the current abstraction level. If you’ve used the >>> try: Don’t Overwhelming ExceptionsEarlier we mentioned that exception capture should be
precise and the abstraction level should be consistent. But in the real world, if you strictly follow these processes, you are likely to run into another problem: too much exception handling logic that disrupts the core logic of the code . The specific performance is that the code is filled with a large number of def upload_profile_pic(request): This is a view function that handles user uploads of profiles. Three things are done in this function, and exceptions are caught for each of them. If an exception occurs while doing something, return a user-friendly error to the front end. Although this processing flow is reasonable, it is obvious that the exception handling logic in the code is a bit “overwhelming”. At first glance, it is all code indentation, and it is difficult to extract the core logic of the code. So, how can we use context managers to improve our exception handling flow? Let’s go straight to the code. class raise_api_error: the above code, we define After using this context manager, the whole function can be made clearer and more concise: def upload_profile_pic(request): ConclusionIn this article, I share three tips related to exception handling:
|