Adding more Exceptions
Adding more Exceptions
What would be the best method to add more exceptions?
- extend the built-in exceptions?
- is there another user extension to add more exceptions
Some examples:
timeout, no data, read error,...
Thanks.
- extend the built-in exceptions?
- is there another user extension to add more exceptions
Some examples:
timeout, no data, read error,...
Thanks.
Re: Adding more Exceptions
https://docs.python.org/3.4/tutorial/er ... exceptions
If you have issues with subclassing exceptions (or other builtin types) in MicroPython, please submit bug describing your use case and providing test case to reproduce your issue.
If you have issues with subclassing exceptions (or other builtin types) in MicroPython, please submit bug describing your use case and providing test case to reproduce your issue.
Awesome MicroPython list
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/
Re: Adding more Exceptions
I'm assuming that you're talking about adding Exceptions from python, and not from C?
As pfalcon suggests, it should be the standard way that python supports extensions.
I threw together a small example to confirm that they work. I created a file called extest.py:
and this is what I got on the pyboard:
As pfalcon suggests, it should be the standard way that python supports extensions.
I threw together a small example to confirm that they work. I created a file called extest.py:
Code: Select all
class MyError(Exception):
pass
def func1():
print("About to throw MyError")
raise MyError
print("After raising MyError")
def func2():
try:
func1()
except MyError:
print("Whoops")
Code: Select all
Micro Python v1.1.1-32-gcd590cb on 2014-06-24; PYBv1.0 with STM32F405RG
Type "help()" for more information.
>>> import extest
>>> extest.func2()
About to throw MyError
Whoops
Re: Adding more Exceptions
I added some arguments to MyError.
I also discovered that currently the only way to get a traceback printed is to pass the exception out to the REPL. There doesn't seem to be any way for the python code to print a traceback and retain control.
Updated example:
Results of running unix version:
The results running on pyboard are similar, except the fiename is slightly different.
I also discovered that currently the only way to get a traceback printed is to pass the exception out to the REPL. There doesn't seem to be any way for the python code to print a traceback and retain control.
Updated example:
Code: Select all
class MyError(Exception):
pass
def func1():
print("About to throw MyError")
raise MyError("some args", 57)
print("After raising MyError")
def func2():
try:
func1()
except MyError as ex:
print("Whoops")
raise ex
func2()
Code: Select all
>./micropython ../../extest.py
About to throw MyError
Whoops
Traceback (most recent call last):
File "../../extest.py", line 16, in <module>
File "../../extest.py", line 14, in func2
File "../../extest.py", line 14, in func2
File "../../extest.py", line 11, in func2
File "../../extest.py", line 6, in func1
MyError: ('some args', 57)
Re: Adding more Exceptions
Thank you for the prompt reply.
In fact I was talking about a C exception to be raised from C and caught in MP. I made the modifications in the C firmware, but I was wondering if there is some simpler way to extend the exception (in C) set without modifying the core MP code.
By the way since you mentioned about the trace, I noticed that if exceptions occur from other lower level C code layers, and in the Python code a Try/Exception is added, then the lower level exception messages are hidden and it becomes very hard to know what occurred.
In fact I was talking about a C exception to be raised from C and caught in MP. I made the modifications in the C firmware, but I was wondering if there is some simpler way to extend the exception (in C) set without modifying the core MP code.
By the way since you mentioned about the trace, I noticed that if exceptions occur from other lower level C code layers, and in the Python code a Try/Exception is added, then the lower level exception messages are hidden and it becomes very hard to know what occurred.
Re: Adding more Exceptions
To add to this note, if there is a print in the C code and a Try/Except is added on the Python side, the print in C seems to be masked.
Re: Adding more Exceptions
Exceptions at the C level are really setjmp/longjmp (or conceptually similar).
In C you raise an exception using nlr_raise: like so:
https://github.com/micropython/micropyt ... int.c#L143
To add a custom exception in C, you can just create an your exception as an object derived from Exception.
Right now it looks like MP_DEFINE_EXCEPTION is in objexcept.c and it sounds like it should be moved into a header so that C modules could create their own exceptions. It also looks like some of the required support functions are declared static, and they should probably be exposed.
For an example of catching an exception in C, you can look at:
https://github.com/micropython/micropyt ... int.c#L367
Can you give an example of the hidden try/catch block thing in python? I'm guessing that it can be recoded, but without knowing what your python code looks like it's hard to know if it's a real problem (i.e. bug) or not (i.e. can be recoded).
In C you raise an exception using nlr_raise: like so:
https://github.com/micropython/micropyt ... int.c#L143
To add a custom exception in C, you can just create an your exception as an object derived from Exception.
Right now it looks like MP_DEFINE_EXCEPTION is in objexcept.c and it sounds like it should be moved into a header so that C modules could create their own exceptions. It also looks like some of the required support functions are declared static, and they should probably be exposed.
For an example of catching an exception in C, you can look at:
https://github.com/micropython/micropyt ... int.c#L367
Can you give an example of the hidden try/catch block thing in python? I'm guessing that it can be recoded, but without knowing what your python code looks like it's hard to know if it's a real problem (i.e. bug) or not (i.e. can be recoded).
Re: Adding more Exceptions
I think we'd need to see an example. The print should be happening right when the print statement is called. I'm not aware of any way to mask the print. The only thing I can think of is that it's sitting in the buffer to be sent out over USB serial, and that never happens because something resets USB. In this case if you set things up so that prints go out a UART, you should definitely see the print exactly when it occurs (there is no buffering of any kind which gets in the way of UART prints)nelfata wrote:To add to this note, if there is a print in the C code and a Try/Except is added on the Python side, the print in C seems to be masked.
Re: Adding more Exceptions
Here is an example where the print in C is being masked when using a try/except block in MP:
(the Wiki is changing the tabs)
MP CODE
-----------
while receiveComplete == False:
try:
d = self.client_s.read(size, flags, timeout_ms*10)
except NoDataError:
print('no data error in read')
continue
except:
# some error occurred, we may need to restart the connection
self.errorFlag = 1
print('error in read')
break
C CODE
---------
... some code
status = _sock_isavailable(self->fd, 1, timeout);
RAISE_EXCEP(status>=0, mp_type_ReadError, "read failed");
RAISE_EXCEP(status==0, mp_type_NoDataError, "no data"); <<<<------MP is detecting this exception (exception message is masked)
....
STATIC int _sock_isavailable(int fd, int r_or_w, int timeout_ms)
{
...some code...
rc = cc3k_sock_select(fd+1, fd_read, fd_write, NULL, ptimeout);
if(rc == 0)
{ // select timed out, no data available
printf("select timedout\n"); <<<<<-------MP is masking this printf
}
NOTE: I created new exceptions here ReadError and NoDataError.
#define RAISE_EXCEP(assertion, type, msg) { if ((assertion) == 0) nlr_raise(mp_obj_new_exception_msg(&(type), (msg))); }
(the Wiki is changing the tabs)
MP CODE
-----------
while receiveComplete == False:
try:
d = self.client_s.read(size, flags, timeout_ms*10)
except NoDataError:
print('no data error in read')
continue
except:
# some error occurred, we may need to restart the connection
self.errorFlag = 1
print('error in read')
break
C CODE
---------
... some code
status = _sock_isavailable(self->fd, 1, timeout);
RAISE_EXCEP(status>=0, mp_type_ReadError, "read failed");
RAISE_EXCEP(status==0, mp_type_NoDataError, "no data"); <<<<------MP is detecting this exception (exception message is masked)
....
STATIC int _sock_isavailable(int fd, int r_or_w, int timeout_ms)
{
...some code...
rc = cc3k_sock_select(fd+1, fd_read, fd_write, NULL, ptimeout);
if(rc == 0)
{ // select timed out, no data available
printf("select timedout\n"); <<<<<-------MP is masking this printf
}
NOTE: I created new exceptions here ReadError and NoDataError.
#define RAISE_EXCEP(assertion, type, msg) { if ((assertion) == 0) nlr_raise(mp_obj_new_exception_msg(&(type), (msg))); }
Re: Adding more Exceptions
dhylands wrote:I think we'd need to see an example. The print should be happening right when the print statement is called. I'm not aware of any way to mask the print. The only thing I can think of is that it's sitting in the buffer to be sent out over USB serial, and that never happens because something resets USB. In this case if you set things up so that prints go out a UART, you should definitely see the print exactly when it occurs (there is no buffering of any kind which gets in the way of UART prints)nelfata wrote:To add to this note, if there is a print in the C code and a Try/Except is added on the Python side, the print in C seems to be masked.
Could it be that we need to flush the printf (fflush(stdout)) when using the USB serial?