473,554 Members | 2,919 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Re-raising exceptions with modified message

What is the best way to re-raise any exception with a message
supplemented with additional information (e.g. line number in a
template)? Let's say for simplicity I just want to add "sorry" to every
exception message. My naive solution was this:

try:
...
except Exception, e:
raise e.__class__, str(e) + ", sorry!"

This works pretty well for most exceptions, e.g.
>>try:
.... 1/0
.... except Exception, e:
.... raise e.__class__, str(e) + ", sorry!"
....
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
ZeroDivisionErr or: integer division or modulo by zero, sorry!

But it fails for some exceptions that cannot be instantiated with a
single string argument, like UnicodeDecodeEr ror which gets "converted"
to a TypeError:
>>try:
.... unicode('\xe4')
.... except Exception, e:
.... raise e.__class__, str(e) + ", sorry!"
....
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
TypeError: function takes exactly 5 arguments (1 given)

Another approach is using a wrapper Extension class:

class SorryEx(Excepti on):
def __init__(self, e):
self._e = e
def __getattr__(sel f, name):
return getattr(self._e , name)
def __str__(self):
return str(self._e) + ", sorry!"

try:
unicode('\xe4')
except Exception, e:
raise SorryEx(e)

But then I get the name of the wrapper class in the message:

__main__.SorryE x: 'ascii' codec can't decode byte 0xe4 in position 0:
ordinal not in range(128), sorry!

Yet another approach would be to replace the __str__ method of e, but
this does not work for new style Exceptions (Python 2.5).

Any suggestions?

-- Chris
Jul 5 '07 #1
28 5855
Christoph Zwerschke schrieb:
What is the best way to re-raise any exception with a message
supplemented with additional information (e.g. line number in a
template)?
I have the impression that you do NOT want to change the exceptions,
instead you want to print the traceback in a customized way. But I may be wrong...

Thomas

Jul 5 '07 #2
Thomas Heller wrote:
I have the impression that you do NOT want to change the exceptions,
instead you want to print the traceback in a customized way. But I may be wrong...
No, I really want to modify the exception, supplementing its message
with additional information about the state of the program.

The use case are compiled Kid templates (http://kid-templating.org). If
an error occurs, I want to add the corresponding line number of the XML
file as information for the template developer. Since the final error
handling may happen somewhere else (e.g. by TurboGears importing a Kid
template), I do not want to modify trackeback handling or something.

-- Chris
Jul 5 '07 #3
On Jul 5, 3:53 pm, Christoph Zwerschke <c...@online.de wrote:
What is the best way to re-raise any exception with a message
supplemented with additional information (e.g. line number in a
template)? Let's say for simplicity I just want to add "sorry" to every
exception message. My naive solution was this:

try:
...
except Exception, e:
raise e.__class__, str(e) + ", sorry!"

This works pretty well for most exceptions, e.g.
>>try:
... 1/0
... except Exception, e:
... raise e.__class__, str(e) + ", sorry!"
...
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
ZeroDivisionErr or: integer division or modulo by zero, sorry!

But it fails for some exceptions that cannot be instantiated with a
single string argument, like UnicodeDecodeEr ror which gets "converted"
to a TypeError:
>>try:
... unicode('\xe4')
... except Exception, e:
... raise e.__class__, str(e) + ", sorry!"
...
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
TypeError: function takes exactly 5 arguments (1 given)

Another approach is using a wrapper Extension class:

class SorryEx(Excepti on):
def __init__(self, e):
self._e = e
def __getattr__(sel f, name):
return getattr(self._e , name)
def __str__(self):
return str(self._e) + ", sorry!"

try:
unicode('\xe4')
except Exception, e:
raise SorryEx(e)

But then I get the name of the wrapper class in the message:

__main__.SorryE x: 'ascii' codec can't decode byte 0xe4 in position 0:
ordinal not in range(128), sorry!

Yet another approach would be to replace the __str__ method of e, but
this does not work for new style Exceptions (Python 2.5).

Any suggestions?

-- Chris
If you are sure that the exception isn't caught on another level just
use the following showtraceback() function, manipulate it's output
slightly and terminate your program with sys.exit()

def showtraceback() :
'''
(Copied from code.py)
'''
try:
type, value, tb = sys.exc_info()
sys.last_type = type
sys.last_value = value
sys.last_traceb ack = tb
tblist = traceback.extra ct_tb(tb)
del tblist[:1]
lst = traceback.forma t_list(tblist)
if lst:
lst.insert(0, "Traceback (most recent call last):\n")
lst[len(lst):] = traceback.forma t_exception_onl y(type,
value)
finally:
tblist = tb = None
sys.stderr.writ e("".join(lst ))
Jul 5 '07 #4
Kay Schluehr wrote:
If you are sure that the exception isn't caught on another level just
use the following showtraceback() function, manipulate it's output
slightly and terminate your program with sys.exit()
That's what I want to avoid. In my case the error is displayed and
evaluated in a completly different piece of software.

-- Chris
Jul 5 '07 #5
Seems that no simple solution exists,
so for now, I will be using something like this:

class PoliteException (Exception):
def __init__(self, e):
self._e = e
def __getattr__(sel f, name):
return getattr(self._e , name)
def __str__(self):
if isinstance(self ._e, PoliteException ):
return str(self._e)
else:
return '\n%s: %s, I am sorry!' % (
self._e.__class __.__name__, str(self._e))

try:
unicode('\xe4')
except Exception, e:
raise PoliteException (e)
Jul 5 '07 #6
On Jul 6, 12:21 am, Christoph Zwerschke <c...@online.de wrote:
Kay Schluehr wrote:
If you are sure that the exception isn't caught on another level just
use the following showtraceback() function, manipulate it's output
slightly and terminate your program with sys.exit()

That's what I want to avoid. In my case the error is displayed and
evaluated in a completly different piece of software.

-- Chris
Probably the simplest solution would be to create a new exception and
wrapping the old one and the additional info. Unfortunately,
this may have a huge impact on 3rd party code that was catching the
original exception.

So, I think you should create an utility factory-like function that is
either creating a new exception instance as the one caught
and with the additional information, or an utility that knows how to
modify the caught exception according to its type.
In the first case you will need somehow to tell to the new instance
exception the real stack trace, because by simply raising
a new one the original stack trace may get lost.

bests,

../alex
--
..w( the_mindstorm )p.

Jul 5 '07 #7
Sorry for the soliloquy, but what I am really using is the following so
that the re-raised excpetion has the same type:

def PoliteException (e):
class PoliteException (e.__class__):
def __init__(self, e):
self._e = e
def __getattr__(sel f, name):
return getattr(self._e , name)
def __str__(self):
if isinstance(self ._e, PoliteException ):
return str(self._e)
else:
return '\n%s: %s, I am sorry!' % (
self._e.__class __.__name__, str(self._e))
return PoliteException (e)

try:
unicode('\xe4')
except Exception, e:
raise PoliteException (e)

Jul 5 '07 #8
Alex Popescu wrote:
Probably the simplest solution would be to create a new exception and
wrapping the old one and the additional info. Unfortunately, this
may have a huge impact on 3rd party code that was catching the
original exception. So, I think you should create an utility
factory-like function that is either creating a new exception
instance as the one caught and with the additional information,
Right, I have gone with that (see the example with the PoliteException
class somewhere below).
or an utility that knows how to modify the caught exception according
to its type.
I guess you mean something like this (simplified):

except Exception, e:
if getattr(e, 'reason'):
e.reason += "sorry"
else:
e.message += "sorry"

The problem is that these attribute names are not standardized and can
change between Python versions. Not even "args" is sure, and if a class
has "message" it does not mean that it is displayed. Therefore I think
the first approach is better.
In the first case you will need somehow to tell to the new instance
exception the real stack trace, because by simply raising
a new one the original stack trace may get lost.
Yes, but thats a different problem that is easy to solve.

-- Chris
Jul 6 '07 #9
On Jul 6, 4:20 am, Christoph Zwerschke <c...@online.de wrote:
Alex Popescu wrote:
Jul 6 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
4275
by: Nel | last post by:
I have a question related to the "security" issues posed by Globals ON. It is good programming technique IMO to initialise variables, even if it's just $foo = 0; $bar = ""; Surely it would be better to promote better programming than rely on PHP to compensate for lazy programming?
4
6413
by: Craig Bailey | last post by:
Anyone recommend a good script editor for Mac OS X? Just finished a 4-day PHP class in front of a Windows machine, and liked the editor we used. Don't recall the name, but it gave line numbers as well as some color coding, etc. Having trouble finding the same in an editor that'll run on OS X. -- Floydian Slip(tm) - "Broadcasting from...
1
4083
by: Chris | last post by:
Sorry to post so much code all at once but I'm banging my head against the wall trying to get this to work! Does anyone have any idea where I'm going wrong? Thanks in advance and sorry again for adding so much code... <TABLE border="1" bordercolor="#000000" cellspacing="0"> <TR>
11
3991
by: James | last post by:
My form and results are on one page. If I use : if ($Company) { $query = "Select Company, Contact From tblworking Where ID = $Company Order By Company ASC"; }
4
18519
by: Alan Walkington | last post by:
Folks: How can I get an /exec'ed/ process to run in the background on an XP box? I have a monitor-like process which I am starting as 'exec("something.exe");' and, of course the exec function blocks until something.exe terminates. Just what I /don't/ want. (Wouldn't an & be nice here! Sigh) I need something.exe to disconnect and...
1
3689
by: John Ryan | last post by:
What PHP code would I use to check if submitted sites to my directory actually exist?? I want to use something that can return the server code to me, ie HTTP 300 OK, or whatever. Can I do this with sockets??
10
4199
by: James | last post by:
What is the best method for creating a Web Page that uses both PHP and HTML ? <HTML> BLA BLA BLA BLA BLA
8
3647
by: Lothar Scholz | last post by:
Because PHP5 does not include the mysql extension any more is there a chance that we will see more Providers offering webspace with Firebird or Postgres Databases ? What is your opinion ? I must say that i like it to see mysql replaced by a real database (stored procedures etc.)
1
3626
by: joost | last post by:
Hello, I'm kind of new to mySQL but more used to Sybase/PHP What is illegal about this query or can i not use combined query's in mySQL? DELETE FROM manufacturers WHERE manufacturers_id NOT IN ( SELECT manufacturers_id FROM products )
2
106589
by: sky2070 | last post by:
i have two file with jobapp.html calling jobapp_action.php <HTML> <!-- jobapp.html --> <BODY> <H1>Phop's Bicycles Job Application</H1> <P>Are you looking for an exciting career in the world of cyclery? Look no further! </P> <FORM NAME='frmJobApp' METHOD=post ACTION="jobapp_action.php"> Please enter your name:
0
7521
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7802
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
1
7563
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7889
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
1
5436
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5155
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3560
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3548
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1134
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.