473,796 Members | 2,599 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Semantics of propagated exceptions

Hi,

I wonder how to solve the following problem the most pythonic way:

Suppose you have a function f which, as part of its protocol, raises some
standard exception E under certain, well-defined circumstances. Suppose
further that f calls other functions which may also raise E. How to best
distinguish whether an exception E raised by f has the meaning defined by
the protocol or just comes from details of the implementation?

As an example, let's inherit from dict and replace __getitem__. It is
supposed to raise a KeyError if an item is not found in the mapping. But
what if it does some magic to use default values:

def __getitem__(sel f, key):
if key in self:
return self[key]
defaults = foobar["default"]
return defaults[key]

If "default" is not in foobar, a KeyError is raised by that lookup and
propagates to the calling code. However, the problem is not "key can't be
found" but "I'm too stupid to find out whether key can be found". In a web
context where key identifies the resource requested, this might make the
difference between a 404 "Not found" and a 500 "Internal server error"
response.

Several solutions come to mind, neither of which I'm satisfied with:

- f might catch E exceptions from the implementation and raise some other
error in their stead, maybe with an appropriate message or treating the
traceback in some helpful way. This destroys the original exception.

- f might catch and re-raise E exceptions, setting some flag on them that
identifies them as protocol exceptions or not. This requires calling code
to know about the flag.

- Calling code might guess whether the exception comes from some inner
working of f from how deep in the calling stack the exception originated.
Obviously, this will not be easy or not even work at all if f calls
related functions which might also raise E with the protocol semantics.
This requires calling code to do some magic but keeps f from having to
catch and raise exceptions all over the place.

Some gut feeling tells me the first option is preferrable, but I'ld like
to read your opinions and maybe other alternatives.

--
Thomas
Jul 21 '06 #1
5 1210
In message <pa************ *************** *@ID-174572.user.uni-berlin.de>,
Thomas Lotze wrote:
Suppose you have a function f which, as part of its protocol, raises some
standard exception E under certain, well-defined circumstances. Suppose
further that f calls other functions which may also raise E. How to best
distinguish whether an exception E raised by f has the meaning defined by
the protocol or just comes from details of the implementation?
You can't. All the information necessary to identify the exception must be
in the exception object itself. If you want to distinguish between
exceptions raised by F and those raised by other functions called by F,
then they must be different exceptions.
Jul 21 '06 #2
In <pa************ *************** *@ID-174572.user.uni-berlin.de>, Thomas
Lotze wrote:
I wonder how to solve the following problem the most pythonic way:

Suppose you have a function f which, as part of its protocol, raises some
standard exception E under certain, well-defined circumstances. Suppose
further that f calls other functions which may also raise E. How to best
distinguish whether an exception E raised by f has the meaning defined by
the protocol or just comes from details of the implementation?

[…]

Several solutions come to mind, neither of which I'm satisfied with:

- f might catch E exceptions from the implementation and raise some other
error in their stead, maybe with an appropriate message or treating the
traceback in some helpful way. This destroys the original exception.
This is the way to go I think. After all it's not an ordinary `E` but one
that has a special, well defined meaning if raised by `f` itself according
to your protocol.

Put the original exception as an attribute to the new one and/or subclass
the new exception type from `E`. This way calling code can choose to to
handle both types as `E` if the distinction is not important.

Ciao,
Marc 'BlackJack' Rintsch
Jul 21 '06 #3
Thomas Lotze wrote:
Hi,

I wonder how to solve the following problem the most pythonic way:

Suppose you have a function f which, as part of its protocol, raises some
standard exception E under certain, well-defined circumstances. Suppose
further that f calls other functions which may also raise E. How to best
distinguish whether an exception E raised by f has the meaning defined by
the protocol or just comes from details of the implementation?

As an example, let's inherit from dict and replace __getitem__. It is
supposed to raise a KeyError if an item is not found in the mapping. But
what if it does some magic to use default values:

def __getitem__(sel f, key):
if key in self:
return self[key]
defaults = foobar["default"]
return defaults[key]

If "default" is not in foobar, a KeyError is raised by that lookup and
propagates to the calling code. However, the problem is not "key can't be
found" but "I'm too stupid to find out whether key can be found". In a web
context where key identifies the resource requested, this might make the
difference between a 404 "Not found" and a 500 "Internal server error"
response.
The obvious response is to make the implementation less stupid by
replacing the last statement with

try:
return defaults[key]
except KeyError:
raise KeyError("No default for key value %s" % key)
Several solutions come to mind, neither of which I'm satisfied with:

- f might catch E exceptions from the implementation and raise some other
error in their stead, maybe with an appropriate message or treating the
traceback in some helpful way. This destroys the original exception.
My "solution", of course, takes this approach. The error can readily be
recognised as different from the standard KeyError message. The original
exception is worthless in this context as your new type is clearly
supposed to provide a default for any absent key value. The handling
code should thus treat the key's absence as some sort of implementation
error.
- f might catch and re-raise E exceptions, setting some flag on them that
identifies them as protocol exceptions or not. This requires calling code
to know about the flag.
This doesn't seem particularly helpful in your case. Since the purpose
of the flag is to distinguish the actual exception thrown by your type
from the exception thrown during method execution it would seem more
direct to use a different exception altogether.

- Calling code might guess whether the exception comes from some inner
working of f from how deep in the calling stack the exception originated.
Obviously, this will not be easy or not even work at all if f calls
related functions which might also raise E with the protocol semantics.
This requires calling code to do some magic but keeps f from having to
catch and raise exceptions all over the place.
The problem with this approach is that the more complex your
implementations become, the more complex the client (calling) code has
to be. It will probably also require serious changes to the calling code
as implementation details change, which doesn't give very good isolation.
Some gut feeling tells me the first option is preferrable, but I'ld like
to read your opinions and maybe other alternatives.
Just my two cents worth.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Jul 21 '06 #4
In article
<pa************ *************** *@ID-174572.user.uni-berlin.de>,
Thomas Lotze <th****@thoma s-lotze.dewrote:
Suppose you have a function f which, as part of its protocol, raises some
standard exception E under certain, well-defined circumstances. Suppose
further that f calls other functions which may also raise E. How to best
distinguish whether an exception E raised by f has the meaning defined by
the protocol or just comes from details of the implementation?
My recommendation is to define your own exception type(s), and have f
raise it (them) for errors that are truly generated by f. Or, if you
really want to use one of the existing exception types, then perhaps you
can catch the exceptions from functions called by f, within f itself,
and raise some other error (or suppress the errors, if appropriate).

Cheers,
-M

--
Michael J. Fromberger | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA
Jul 21 '06 #5
Sorry for not answering such a long time. It's because my question
originated from a discussion within our company which moved out of focus
shortly after I posted, and over waiting for some response from them
before replying here, I forgot about it.
Steve Holden wrote:
>- f might catch E exceptions from the implementation and raise some
other error in their stead, maybe with an appropriate message or
treating the traceback in some helpful way. This destroys the original
exception.
My "solution", of course, takes this approach.
Good to see that my "gut feeling" as to the most pythonic approach seems
to coincide with the answers I've received ;o)

--
Thomas
Aug 1 '06 #6

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

Similar topics

0
5759
by: Mehek | last post by:
I tried setting up a Merge Replication between a MSDE (Pull Subscription) and Sql Server 2000 (Publisher) and got the following error: The process could not enumerate changes at the 'Subscriber'. Then I created another subscription, but this time, a PUSH, and this time I got the error "The process could not connect to Subsciber". I tried creating a second PULL Subscription, but the error I got was:
5
2571
by: juergen perlinger | last post by:
Hello out there. sometimes I need to have proper control of the floating point arithmetic of the C(and C++) runtime system, and using the f.p. exception handling of the C99 standard is quite handy for that purpose. The only problem when dealing with f.p. exception signals is that there is (afaik) no specification *when* the f.p. exception is raised, with one notable exception: 'feraiseexcept(int)' raises the exceptions passed in the...
14
2178
by: Dan Jacobson | last post by:
How is this for correct HTML 4.01 headers?: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="zh-tw"><head> <meta http-equiv="Content-Type" content= "text/html; charset=utf-8"> <meta http-equiv="Content-Language" content="zh-tw"> And for my English pages, en-us instead of zh-tw. Did I screw up any details? utf-8 or UTF-8 like Google? The page should work via http:// or file:///.
27
5977
by: v4vijayakumar | last post by:
what "enabling unwind semantics" occording to Microsoft (R) 32-bit C/C++ Optimizing Compiler. C:\Program Files\Microsoft Visual C++ Toolkit 2003\include\ostream(574) : warnin g C4530: C++ exception handler used, but unwind semantics are not enabled. Speci fy /EHsc
9
2205
by: Mike Krell | last post by:
I'm reading Alex Martelli's "Nutshell" second edition. In the section called "Cooperative superclass method calling", he presents a diamond inheritance hierachy: class A(object): def met(self): print "A.met" class B(A): def met(self): print "B.met"
9
1823
by: Dilip | last post by:
Is my understanding right here? An object becomes totally inaccessible only after its dtor runs through completely, right? I have a situation where I need to hang around in the dtor of an automatic object for a while -- this is to let various threads that have access to my automatic object shutdown gracefully. I do not want main() to return when myclass::runInfinitely() happens to
35
2864
by: dragoncoder | last post by:
Just a simple theoritical question to the experts. What was the rationale behind making STL containers follow copy semantics rather than reference semantics. References almost always make things easier without much of overhead. Then why not reference ? Thanks /P
10
2254
by: gauss010 | last post by:
Suppose I have an object A of type char. Each A is a buffer containing a string, and I want to sort the M strings of A using the strcmp function. The description of the qsort function says that I must pass a pointer to the first object of the array to be sorted. This leads me to write the following: char A; int cmp(const void *a, const void *b) { int v = strcmp(*(char (*))a, *(char (*))b); if (v < 0) return -1;
2
1451
by: =?Utf-8?B?QU1lcmNlcg==?= | last post by:
I would like to define a structure or a class with an array field that behaves like a simple value-semantics variable. For example, I want something like public structure polynomial public a() as double ' the polynomial coefficients ... end structure that will behave like
0
10237
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...
1
10187
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 most users, this new feature is actually very convenient. If you want to control the update process,...
0
10018
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...
1
7553
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 instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6795
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
5446
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
5578
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4120
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
2
3735
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.