473,805 Members | 2,008 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
28 5900
On Jul 6, 4:20 am, Christoph Zwerschke <c...@online.de wrote:
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.
Yeah maybe for a python guy, but I am a newbie. I would really
appreciate if you can show in this thread how this can be done in
Python.

tia,

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

PS: sorry for reposting, but it looks like my previous message hasn't
gone through :-(.

Jul 6 '07 #11
On 2007-07-06, Alex Popescu <th************ ***********@gma il.comwrote:
On Jul 6, 4:20 am, Christoph Zwerschke <c...@online.de wrote:
>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.

Yeah maybe for a python guy, but I am a newbie. I would really
appreciate if you can show in this thread how this can be done
in Python.
Chech out the docs for sys.exc_info(), and for the raise
statement.

When handling an exception, you can rethrow a different
exception, but with the same traceback, by using the three-arg
version of raise.

See one of my earlier posts in this thread for a working example
(although it didn't solve Chris's problem).

--
Neil Cerutti
Jul 6 '07 #12
On Jul 6, 12:18 am, Christoph Zwerschke <c...@online.de wrote:
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)
Would a decorator work here?
class PoliteException (Exception):
def __init__(self, e):
self._e = e
def __getattr__(sel f, name):
return getattr(self._e , name)
def __str__(self):
return '\n%s: %s, I am sorry!' % (
self._e.__class __.__name__, str(self._e))

def politefail(fn):
def wrapper(*args, **kwargs):
try:
return fn(*args, **kwargs)
except Exception, e:
raise PoliteException (e)
return wrapper

@politefail
def funktion():
unicode('\xe4')

funktion()

@politefail
def raise_exception (err, *args):
raise err(*args)
def funktion():
if 1 != 2:
raise_exception (ArithmeticErro r, '1 is not equal to 2.')

print
funktion()

Jul 6 '07 #13
Gerard Flanagan wrote:
Would a decorator work here?
Depends on how you want to use that functionality. In my use case I only
need to catch the excpetion once.

Note that in your code the exception has not the right type which is
what I targeted in my last posting. I.e. the following will raise an
Exception if function is decorated:

try:
print funktion()
except ArithmeticError :
pass

-- Chris
Jul 7 '07 #14
On Jul 5, 8:53 am, 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
Can "try" statements be used in "except" clauses? It appears so, thus
a hybrid approach might work well enough.

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

That leaves the issue of the name being changed for
UnicodeDecodeEr ror, which might be fixable by diddling with __name__
properties. Or perhaps SorryEx needs to be a factory that returns
exception classes; the last line would be "SorryEx(e) ()". I'll have
to play with this a bit.

Jul 7 '07 #15
On Jul 7, 4:13 pm, samwyse <samw...@gmail. comwrote:
On Jul 5, 8:53 am, 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)?
[...]
That leaves the issue of the name being changed for
UnicodeDecodeEr ror, which might be fixable by diddling with __name__
properties. Or perhaps SorryEx needs to be a factory that returns
exception classes; the last line would be "SorryEx(e) ()". I'll have
to play with this a bit.
OK, the following mostly works. You probably want the factory to copy
more of the original class into the SorryEx class each time, since
someone catching an exception may expect to look at things besides its
string representation.

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

def test(code):
try:
code()
except Exception, e:
try:
raise e.__class__, str(e) + ", sorry!"
except TypeError:
raise SorryFactory(e) ()

test(lambda: unicode('\xe4') )
Jul 7 '07 #16
Did you run this?
With Py < 2.5 I get a syntax error, and with Py 2.5 I get:

new.__class__ = old.__class__
TypeError: __class__ must be set to a class

-- Chris
Jul 8 '07 #17
samwyse wrote:
def test(code):
try:
code()
except Exception, e:
try:
raise e.__class__, str(e) + ", sorry!"
except TypeError:
raise SorryFactory(e) ()
Ok, you're suggestig the naive approach if it works and the factory
approach I came up with last as a fallback. Maybe a suitable compromize.

-- Chris
Jul 8 '07 #18
On Jul 12, 6:31 am, samwyse <samw...@gmail. comwrote:
On Jul 8, 8:50 am, Christoph Zwerschke <c...@online.de wrote:
With Py 2.5 I get:
new.__class__ = old.__class__
TypeError: __class__ must be set to a class

Hmmm, under Python 2.4.X, printing repr(old.__clas s__) gives me this:
<class exceptions.Unic odeDecodeError at 0x00A24F00>
while under 2.5.X, I get this:
<type 'exceptions.Uni codeDecodeError '>
So, let's try sub-classing the type:

def modify_message( old, f):
class Empty: pass
new = Empty()
print "old.__clas s__ =", repr(old.__clas s__)
print "Empty =", repr(Empty)
new.__class__ = Empty

class Excpt(old.__cla ss__): pass
print "Excpt =", repr(Excpt)
print "Excpt.__class_ _ =", repr(Excpt.__cl ass__)
new.__class__ = Excpt

new.__dict__ = old.__dict__.co py()
new.__str__ = f
return new

Nope, that gives us the same message:

old.__class__ = <type 'exceptions.Uni codeDecodeError '>
Empty = <class __main__.Empty at 0x00AB0AB0>
Excpt = <class '__main__.Excpt '>
Excpt.__class__ = <type 'type'>
Traceback (most recent call last):
[...]
TypeError: __class__ must be set to a class

Excpt ceratinly appears to be a class. Does anyone smarter than me
know what's going on here?

Jul 12 '07 #19
samwyse wrote:
TypeError: __class__ must be set to a class

Excpt ceratinly appears to be a class. Does anyone smarter than me
know what's going on here?
Not that I want to appear smarter, but I think the problem here is that
exceptions are new-style classes now, whereas Empty is an old-style
class. But even if you define Empty as a new-style class, it will not
work, you get:

TypeError: __class__ assignment: only for heap types

This tells us that we cannot change the attributes of a built-in
exception. If it would be possible, I simply would have overridden the
__str__ method of the original exception in the first place.

-- Chris
Jul 13 '07 #20

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

Similar topics

1
4325
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
6431
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 the dark side of the moon"
1
4102
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
4016
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
18544
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 run in the background while I
1
3706
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
4228
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
3662
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
3641
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
106621
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
9716
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10604
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. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10356
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10103
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 choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9179
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6874
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 into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5536
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 the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5676
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4316
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.