4

I need to force an exception to be raised outside a function that does this:

def foo(x):
   try:
     some_calculation(x)
   except:
     print("ignore exception")

Is there a way to override the catch-all inside foo? I would like to raise an exception inside some_calculation(x) that can be caught or detected outside foo.

FYI, foo is a third party function I have no control over.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Arun
  • 41
  • 3
  • 3
    Looks like an HR problem. Don't hire people who write such code. Or a mentoring problem. Teach them why not to swallow exceptions. Or a code review problem: teach people to not let this slide by. – Robert Aug 24 '22 at 15:36
  • A bare `except:` catches any and all exceptions (strictly [`BaseException`s](https://docs.python.org/3/library/exceptions.html#exception-hierarchy)), including e.g. keyboard interrupts, which is why it's not recommended to start with. – jonrsharpe Aug 24 '22 at 15:36
  • 1
    Not even the control to fire the third party, or switch away from using anything they wrote? – Charles Duffy Aug 24 '22 at 15:44
  • You can certainly write a function with side effects -- one that stores a copy of any exception it throws in a global, f/e, making the caller responsible for checking that global's value (much like `errno` in C). – Charles Duffy Aug 24 '22 at 15:45
  • 1
    @Robert FYI This is in a third party function: not one developed in house – Arun Aug 24 '22 at 15:49

1 Answers1

4

No. Your options are:

  • submit a fix to the library maintainers
  • fork the library, and provide your own vendorised version
  • monkey patch the library on import

The last is perhaps the easiest and quickest to get up and running.

Example:

main.py

# before doing anything else import and patch the third party library
# we need to patch foo before anyone else has a chance to import or use it
import third_party_library

# based off of third_party_library version 1.2.3
# we only catch Exception rather than a bare except
def foo(x):
   try:
     some_calculation(x)
   except Exception:
     print("ignore exception")

third_party_library.foo = foo

# rest of program as usual
...

Things might be slightly more complicated than that if foo() is re-exported across several different modules (if the third party library has its own from <x> import foo statements. But if just requires monkey patching more attributes of the various re-exporting modules.

Technically it would be possible to force an exception to be raised, but it would involve setting an execution trace and forcing an exception to be thrown in the exception handling code of the foo(). It would be weird, the exception would appear to come from print("ignore exception") rather than some_calculation(x). So don't do that.

Dunes
  • 37,291
  • 7
  • 81
  • 97