having problems with python error handlers - python

hello I am pretty new into python , but I am trying to handle errors, however when I try to ctrl + C or L I got input > ^Cerror which it should be only display error and not ^C or ^L how can I fix this ?
except KeyboardInterrupt:
print("error")
except Exception as e:
raise e

You can back up and overwrite it, but you can't "fix" it. That character comes from the keyboard echo of the symbiont terminal: your stdin processor is set to echo (print to screen) whatever is typed. That ^C couplet is printed by this I/O processing before your program gets to handle the exception. Thus, the \r option (or a sequence of backspaces, \b) is likely your best remedy.
import sys
try:
while True:
string = input("Show me something")
except KeyboardInterrupt:
print("\b\b error")
except Exception as e:
raise e
Output, with CTRL-C at keyboard:
Show me something error
If you want to wipe out the entire input line, use \r instead:
except KeyboardInterrupt:
print("\rerror", " "*80)
Output:
Show me something -- this line appears until I hit CTRL-C. Replaced by
error

Related

Python debugging in eclipse stop on outer except block

I have nested exceptions handling in my code, when inner blocks do some stuff before re-raising the exception to upper layers.
Traceback always reports the line number that started the exception handling.
However, when running in UI debugger (Pydev/Eclipse) it stops on the outer exception block in some cases.
Consider the following code for example:
import sys
def f(a):
c=5/a
return c
def sub(d):
print("Entered sub(%d)" % d)
try:
print("Entered try #sub")
e = f(d)/(d-1)
return e
except:
print("Do some staff before re-raising the exception upwards")
raise
def main():
try:
print("Entered try #main")
d = int(sys.argv[1])
sub(d)
except:
print("Reached except block #main")
raise
if __name__ == '__main__':
main()
When running with argument = 0, the exception is caused at line#4 and the debugger stops on that line:
However, when running with argument = 1, the exception is caused at line#11 (as reported in the printed traceback) but the debugger stops at line#15.
Once the debugger stops at the incorrect location it is very difficult to watch internal variables and handle the error, especially when the code in the try block uses loops.
In Pydev->Manage Exceptions, I checked only the "suspend on uncaught exceptions".
There is a checkbox "Skip exceptions caught in same function" that seem related (because it seems like the debugger skipped the first exception in sub and stopped on "raise" statement which can be considered another exception in same function, although the documentation says that it should re-raise the same exception).
This checkbox is grayed out unless I first check "Suspend on caught exceptions*", but once enabling it the debugger gets stuck and does not stop anywhere...
Will appreciate your help.
-Moshe

Handling Exceptions in Arduino-Python Communications

I am trying to implement a system where outputs from an Arduino can be passed on to and printed in Python.
I have the following Arduino code snippet below:
void loop() {
if (Serial.available()) {
c = Serial.read();
if (c == '1') {
digitalWrite(pinLED1, HIGH);
digitalWrite(pinLED2, LOW);
//Serial.print("1 ON, 2 OFF\n");
}
My Python code snippet is as follow:
import serial
import time
arduino = serial.Serial('COM3', 9600, timeout=1)
msg = arduino.readline(arduino.inWaiting()) # read everything in the input buffer
time.sleep(3)
ASCIIdata = '121210'
for i in range(len(ASCIIdata)):
if ASCIIdata[i] == '1':
strin = '1'
arduino.write(strin.encode())
time.sleep(0.2)
#print(ASCIIdata[i])
try:
print ("Message from arduino: ")
print arduino.readline()
raise
except Exception as e:
print ("Fail to send!")
In the above example, I am trying to send inputs to Arduino via ASCIIdata, and when it matches the if-statement in Arduino, commands in the if-statement will be executed. I have purposely not do a print in Arduino and attempt to read something from Python by doing:
try:
print ("Message from arduino: ")
print arduino.readline()
raise
except:
print ("Fail to send!")
I observed that if I do not put raise in the try statement, the except statement will not be executed, but the program moves on after the specific timeout. Hence, I put raise in the try statement. May I ask if this is the correct approach to raising an exception?
I read that I should be doing except Exception as e instead of doing except because I would be catching all kinds of exception while the program is running. May I ask if this thought process is correct?
First of all, I'm not very much into Python, so I'm not really sure, but having experience in other languages I think that this answer is correct.
What you did is... wrong. You don't want to raise an exception every time.
Looking at the documentation of the readline function,
readlines() depends on having a timeout and interprets that as EOF
(end of file). It raises an exception if the port is not opened
correctly.
This means that a timeout does not raise exceptions. You can test if the buffer is empty:
try:
print ("Message from arduino: ")
buff = arduino.readline()
print buff
if not buff:
raise
except:
print ("Fail to send!")
Even if you may just skip the exception:
print ("Message from arduino: ")
buff = arduino.readline()
print buff
if not buff:
print ("Fail to send!")
If you prefer another behavior, write your own function (for instance this answer has something which looks like a reading function; you'll just have to add the exception raising.
As for the type of exception, usually it is best to use just one type of exception, in order to avoid catching everything. For instance:
class MyError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
try:
raise MyError(2*2)
except MyError as e:
print 'My exception occurred, value:', e.value
To answer your first question, this is the correct way to catch exceptions. The caveat is that you need to know what exceptions the code inside the try block raises. In your case arduino.readline() will only raise an exception on a serial port issue. In other words you don't need to call raise yourself because that means it will always look like a failure.
Using except Exception as e allows you to handle specific exceptions that code in the try block might raise. This way you can respond in different ways.
For example you might have different response for different errors:
except OSError as err:
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise

Python: pseudo try before actually try and finding exception

I know I'm not clear on this thing but I couldn't be more specific in the title. Consider the following code:
try:
print "Try this out"
a = int("Blah blah")
except:
print "I got the exception"
The output of this code is-
Try this out
I got the exception
What I want the python to do is to check if it might raise an exception in the try: block first and then execute it. Else, just execute the except: block. Is it possible to do such a thing without nesting the multiple try-except blocks.
No, it's not possible, because you get an exception during execution. But you can do like this:
try:
a = int("Blah blah")
print "Try this out"
except:
print "I got the exception"
Your try statement prints up as no error happens in printing it ,but as soon as it tries to execute a, gets an error so except executes.
Try this way to catch the exception properly:
try:
a = int("Blah blah")
print ("Try this out")
except:
print ("I got the exception")

Catching stderr custom output in try catch python

I have a function that will write to stderr when an error occurs:
class Scanner:
...
def next(self):
if ...
...
if not open_comment_count == closed_comment_count:
...
sys.stderr.write("error: unclosed comment at position ({0}, {1})".format(start_position, end_position))
...
break
...
else:
sys.stderr.write("error: illegal character \'{0}\' found " \
"at position #({1}, {2})".format(self.input_text[self.curr_position],
self.curr_position, self.curr_position))
error_flag = 1
break
if error_flag == 0:
token = Token(kind=4, eof_value="eof", start_position=self.curr_position, end_position=self.curr_position)
return token
the function is very long so I included the parts where I write to stderr. What I would like to do is when those errors occur, I want to print those errors and terminate the program. So in my main, I would like to have:
def main():
s = Scanner(input_string)
try:
while(True):
s.next()
except:
# print error message and stop
What i am stuck on is what should the exception be. I want to somehow catch that something was written to stderr and I want that caught and printed out in main and then the program to stop. Basically running until an exception occurs. I know this can be done by writing my own exception, but is it possible to just check if something was written to stderr and then print it out?
What you want to do mixes up concerns: reporting an error becomes a signal that there has been an error. You could do that by creating a wrapper for stderr that sets some kind of flag:
import sys
class MyStdErr(object):
stderr = sys.stderr
waserr = False
def write(self, text):
self.waserr = True
self.stderr.write(text)
sys.stderr = MyStdErr()
Now sys.stderr.waserr is True if stderr was written to at any point.
I think raising an exception containing the error message, catching it, and printing the error (as shown by Nathan) is considerably better, however.
Instead of writing to stderr is there a reason you cant just raise errors with what you're writing to stderr as the message? Then you can just catch whatever error you decide to raise. Something like
class Scanner:
...
def next(self):
if ...
...
if not open_comment_count == closed_comment_count:
...
raise InputError("error: unclosed comment at position ({0}, {1})".format(start_position, end_position))
...
break
...
else:
raise InputError("error: illegal character \'{0}\' found " \
"at position #({1}, {2})".format(self.input_text[self.curr_position],
self.curr_position, self.curr_position))
error_flag = 1
break
if error_flag == 0:
token = Token(kind=4, eof_value="eof", start_position=self.curr_position, end_position=self.curr_position)
return token
and then
def main():
s = Scanner(input_string)
try:
while(True):
s.next()
except InputError as e:
print e
EDIT
to address your comment, yes. And if you want do do it with a custom error name you can do
class MyException(Exception):
pass
and then raise MyException('message')
If you want to cause an exception when you write to stderr, then close stderr. Now when some function writes to stderr, I guess it will get an IOError. Getting the error message will be harder.
You could catch all exceptions and print out the exception, but this still won't capture the message to stderr.

in python , why is there a difference in exception when signal handling is done before and after "try except"

I recently started with python . I was playing with handling the keyboard interrupt , when I came across this behavior
import signal,sys
def handleInt(sign,no):
print "interrupted"
signal.signal(signal.SIGINT,handleInt) # exception raised is IOError
try:
sys.stdin.read(1)
except IOError:
print "io interrupt"
but if I change the signal handling to after the try-except
import signal,sys
def handleInt(sign,no):
print "interrupted"
try:
sys.stdin.read(1)
except KeyboardInterrupt:
print "keyboard interrupt"
signal.signal(signal.SIGINT,handleInt) # exception raised is KeyboardInterrupt
When I press ctrl+c , there is a difference in the exception in the two cases .So why is this behavior ?
Python has its own built-in singal handler for SIGINT. This handler simply raises KeyboardInterrupt. In your first code, you replaced the built-in handler with the new handler hence you see this output:
$python test_exc.py
^Cinterrupted
Note that io interrupted is not printed, since no exception was raised. In fact modifying the code to:
import signal,sys
def handleInt(sign,no):
print "interrupted"
signal.signal(signal.SIGINT, handleInt) # exception raised is IOError
try:
sys.stdin.read(1)
except IOError:
print "io interrupt"
else:
# else is executed only if no exception was raised
print "done"
You get:
$python test_exc.py
^Cinterrupted
done
Note that hitting Ctrl+C does not block the call to sys.stdin.read(1) hence you still have to press some key to let the program continue. Raising an exception inside the signal handler will raise it as if the call to sys.stdin.read(1) produced it:
import signal,sys
def handleInt(sign,no):
print "interrupted"
raise OSError
signal.signal(signal.SIGINT, handleInt) # exception raised is IOError
try:
sys.stdin.read(1)
except IOError:
print "io interrupt"
else:
# else is executed only if no exception was raised
print "done"
Sample run:
$python test_exc.py
^Cinterrupted
Traceback (most recent call last):
File "test_exc.py", line 10, in <module>
sys.stdin.read(1)
File "test_exc.py", line 5, in handleInt
raise OSError
OSError
Note: you can access the default signal handler via signal.default_int_handler.
When you try and register the signal after the blocking call to sys.stdin.read, you never actually get there.
So you get an exception when you hit Ctrl-C which raises a KeyboardInterrupt breaks out of the read and is caught by the try.
When you actually register the signal handler in the first example something slightly different is happening. The interrupt is being handled by your handleInt code.

Categories