[SOLVED]How to catch error signals without try / except

Hi,
First time posting here. I’d like to catch any error signal produced, be it a NameError, IndentationError, or whatnot. I don’t care to escape them, I would just like to be able to call some simple function whenever such an error occurs. Some people might say that this is a bad idea, especially for RuntimeErrors, but this is for an art project where mistakes, when writing code live, should be made apparent in some way, possibly through some kind of auditory display.

I’ve seen the traceback and faulthandler modules, but I’m not sure if these are what I need and how to use them.

For example, the pseudo-code below demonstrates a function I would like to be called when the NameError triggered by the line below it occurs:

# define some variable
avar = 10

def beep():
  # the object below is from a class of the Pyo module for DSP
  trig.play()

# if the variable is called with a spelling error, beep() should somehow be called
# without needing to encapsulate the test below in a try / except structure
if aval < 20:
  print("hello")

Ideally, this mechanism should work for any sort of error signal.

Are you just wanting to run that sound, then let the program continue to crash and quit? If so, you can assign a function to sys.excepthook. It’ll be called with 3 parameters - the exception type, value and traceback - if an exception is completely uncaught and about to crash the interpreter. Otherwise if you want to keep things running, read on.

In that case it makes sense to catch all errors, so the code being written doesn’t bring down the whole application. The way exceptions work is that all exceptions inherit from BaseException, so you can catch that to catch absolutely everything. However you probably want to inherit from Exception instead - there’s only 3 classes that directly inherit from BaseException, specifically to avoid getting caught unnecessarily.

You’d want to have a try-except block, but instead of putting it in your script, write another file that you actually execute, and there have either an import or exec() call inside a try block. Then it’ll even catch syntax errors in the code. If you instead want to have an interactive interpreter prompt like running Python by itself, the code module implements that logic for you as a base to customise. You could subclass InteractiveInterpreter, then override the two methods there to change how errors behave.

What you are calling “error signal” is called an exception.

Why do you want to do this? Is it just to make a beep to catch your
attention?

I know you said you don’t want to use a try…except block, but that
really is the easiest way. Surround your entire application with a
single try…except block:

try:
    main()  # Run your application.
except:
    beep()
    raise

and that’s all it takes. But beware, this technique can be abused in
ways that are very bad programming practice:

Another way is to install an exception hook.

import sys

def myhook(*args):
    beep()
    sys.__excepthook__(*args)

sys.excepthook = myhook

If you can explain why you are trying to do this, we can suggest whether
it is a good idea or not.

The code chunk you provided does exactly what I want! For the information, I want to collaborate with a saxophone player and detect the pitch of his input, where each note will be assigned to one key of the computer keyboard. This way he can use his saxophone to write stuff on my laptop (by using an Arduino Leonardo to do the key strokes). Since this is a rather difficult task, I expect him to make a lot of typos, and I want to have an audible or visible reaction by the computer whenever this happens.

Your code catches exceptions but doesn’t escape it, right? So there’s no issue like the ones in the link you provided.

Thank you both for your replies!

Correct, the excepthook runs immediately before the exception halts the
interpreter. It doesn’t suppress the exception, it just changes how it
is displayed.

But are you sure you have planned this carefully enough?

You want your friend to write Python code by blowing notes into a
saxophone. So if your friend wants to write the code for the classic
“Hello world” program:

# Helloworld.py
print("Hello world!")

he has to think “p is middle-C, r is G, i is B, …” and then play
C-G-B… to get “pri…”.

And then after he has finished “writing” the entire program you run the
code, and if there is an error of any sort, whether it is a typo or
a logic error, your computer plays a beep. And then what?

Be fair! Using Prolog, a mistake in your programme (syntax aside) got
you a bland “no” because the logical expression it represented was
false. Good times.

Cheers,
Cameron Simpson cs@cskk.id.au

Well, the idea is not to type “hello world”. He will be calling classes from the Pyo module for DSP which will process the sound of the saxophone. Anyway, this idea is still in its first stages.

Thanks again for the code chunk!