Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ignore exceptions thrown and caught inside a library

The Python standard library and other libraries I use (e.g. PyQt) sometimes use exceptions for non-error conditions. Look at the following except of the function os.get_exec_path(). It uses multiple try statements to catch exceptions that are thrown while trying to find some environment data.

try:
    path_list = env.get('PATH')
except TypeError:
    path_list = None

if supports_bytes_environ:
    try:
        path_listb = env[b'PATH']
    except (KeyError, TypeError):
        pass
    else:
        if path_list is not None:
            raise ValueError(
                "env cannot contain 'PATH' and b'PATH' keys")
        path_list = path_listb

    if path_list is not None and isinstance(path_list, bytes):
        path_list = fsdecode(path_list)

These exceptions do not signify an error and are thrown under normal conditions. When using exception breakpoints for one of these exceptions, the debugger will also break in these library functions.

Is there a way in PyCharm or in Python in general to have the debugger not break on exceptions that are thrown and caught inside a library without any involvement of my code?

like image 771
Feuermurmel Avatar asked Aug 15 '12 08:08

Feuermurmel


People also ask

How do I ignore an exception?

There is no way to basically ignore a thrown exception. The best that you can do is to limit the standard you have to wrap the exception-throwing code in.

How do I ignore a specific exception in Python?

Using Try Exceptexcept ... block to catch the ZeroDivisionError exception and ignore it. In the above code, we catch the ZeroDivisionError exception and use pass to ignore it. So, when this exception happens, nothing will be thrown and the program will just keep running by ignoring the zero number.

How do you continue if exception occurs in Python?

If an exception occurs during execution of the try clause, the rest of the clause is skipped. Then, if its type matches the exception named after the except keyword, the except clause is executed, and then execution continues after the try/except block.


2 Answers

in PyCharm, go to Run-->View Breakpoints, and check "On raise" and "Ignore library files".

screenshot of the options menu

The first option makes the debugger stop whenever an exception is raised, instead of just when the program terminates, and the second option gives PyCharm the policy to ignore library files, thus searching mainly in your code.

The solution was found thanks to CrazyCoder's link to the feature request, which has since been added.

like image 139
Discordy Avatar answered Oct 19 '22 03:10

Discordy


For a while I had a complicated scheme which involved something like the following:

try( Closeable ignore = Debugger.newBreakSuppression() )
{
   ... library call which may throw ...
} <-- exception looks like it is thrown here

This allowed me to never be bothered by exceptions that were thrown and swallowed within library calls. If an exception was thrown by a library call and was not caught, then it would appear as if it occurred at the closing curly bracket.

The way it worked was as follows:

Closeable is an interface which extends AutoCloseable without declaring any checked exceptions.

ignore is just a name that tells IntelliJ IDEA to not complain about the unused variable, and it is necessary because silly java does not support try( Debugger.newBreakSuppression() ).

Debugger is my own class with debugging-related helper methods.

newBreakSuppression() was a method which would create a thread-local instance of some BreakSuppression class which would take note of the fact that we want break-on-exception to be temporarily suspended.

Then I had an exception breakpoint with a break condition that would invoke my Debugger class to ask whether it is okay to break, and the Debugger class would respond with a "no" if any BreakSuppression objects were instantiated.

That was extremely complicated, because the VM throws exceptions before my code has loaded, so the filter could not be evaluated during program startup, and the debugger would pop up a dialog complaining about that instead of ignoring it. (I am not complaining about that, I hate silent errors.) So, I had to have a terrible, horrible, do-not-try-this-at-home hack where the break condition would look like this: java.lang.System.err.equals( this ) Normally, this would never return true, because System.err is not equal to a thrown exception, therefore the debugger would never break. However, when my Debugger class would get initialized, it would replace System.err with a class of its own, which provided an implementation for equals(Object) and returned true if the debugger should break. So, essentially, I was using System.err as an eternal global variable.

Eventually I ditched this whole scheme because it is overly complicated and it performs very bad, because exceptions apparently get thrown very often in the java software ecosystem, so evaluating an expression every time an exception is thrown tremendously slows down everything.

like image 31
Mike Nakis Avatar answered Oct 19 '22 05:10

Mike Nakis