By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
464,528 Members | 924 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 464,528 IT Pros & Developers. It's quick & easy.

C# Exception is Unchecked???

P: n/a
I am using Visual Studio 2K3 writing a ASP.NET web application. Is there a
way to force the C# compiler to catch possible exception?

In Java, all exceptions thrown MUST BE caught, otherwise compiler would give
you error. In C#, is there a way to do that?

Nov 16 '05 #1
Share this Question
Share on Google+
16 Replies

P: n/a
now you know why I don't use Java.

No, C# will not FORCE you to catch your errors. That's up to you to do, and
it makes sense. You don't always want to catch every error locally. While
it is good practice, it should not be an absolute requirement.

--- Nick

"ChInKPoInt [No MCSD]" <Ch*******************@gmail.com> wrote in message
news:G5********************@rogers.com...
I am using Visual Studio 2K3 writing a ASP.NET web application. Is there a way to force the C# compiler to catch possible exception?

In Java, all exceptions thrown MUST BE caught, otherwise compiler would give you error. In C#, is there a way to do that?

Nov 16 '05 #2

P: n/a
Nick Malik <ni*******@hotmail.nospam.com> wrote:
now you know why I don't use Java.

No, C# will not FORCE you to catch your errors. That's up to you to do, and
it makes sense. You don't always want to catch every error locally. While
it is good practice, it should not be an absolute requirement.


It's not in Java. You don't have to catch every exception (or even
checked exception) locally - you just have to declare which checked
exceptions you can throw.

I believe that checked exceptions of some kind are a good idea; I'm not
sure that Java got it right, and C#/.NET didn't get it right by getting
rid of them entirely. Java feels slightly cumbersome because of them,
and C# sometimes feels like driving without a seatbelt due to the lack
of them. The first language/platform which gets exception handling
really "right" will be interesting...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #3

P: n/a
Nope C# doesn't support checked exceptions. Heres a transcript of Bruce Eckle and Anders Hejlsberg discussing why they are not in C#.

http://www.artima.com/intv/handcuffs.html

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

I am using Visual Studio 2K3 writing a ASP.NET web application. Is there a
way to force the C# compiler to catch possible exception?

In Java, all exceptions thrown MUST BE caught, otherwise compiler would give
you error. In C#, is there a way to do that?
Nov 16 '05 #4

P: n/a

"Richard Blewett [DevelopMentor]" <ri******@NOSPAMdevelop.com> wrote in
message news:uG**************@TK2MSFTNGP10.phx.gbl...
Nope C# doesn't support checked exceptions. Heres a transcript of Bruce
Eckle and Anders Hejlsberg discussing why they are not in C#.

http://www.artima.com/intv/handcuffs.html


I find the "versioning" argument here weak, for two reasons:

The implication is that a method

void M() throws A, B, C

throws precisely A, B and C, and that this handcuffs you in reimplementing
the method. In fact, the method can be changed to throw any subclass of A,
B or C without breaking compatibility. If you're designing a method that
has to remain compatible (one in a widely used library, like the .NET
Framework) A, B and C should be categories of exception like IOException,
not the specific IO exceptions that can be thrown in the first
implementation.

One advantage of checked exceptions is that it allows the documentation to
know which exceptions are thrown. Compare the JDK Javadoc with the .NET API
documentation. You'll see how much better the Javadoc is about showing
which exceptions are thrown and why.
Nov 16 '05 #5

P: n/a
"Mike Schilling" <ms*************@hotmail.com> wrote in message
news:eZ**************@TK2MSFTNGP15.phx.gbl...

"Richard Blewett [DevelopMentor]" <ri******@NOSPAMdevelop.com> wrote in
message news:uG**************@TK2MSFTNGP10.phx.gbl...
Nope C# doesn't support checked exceptions. Heres a transcript of Bruce
Eckle and Anders Hejlsberg discussing why they are not in C#.

http://www.artima.com/intv/handcuffs.html
I find the "versioning" argument here weak, for two reasons:

The implication is that a method

void M() throws A, B, C

throws precisely A, B and C, and that this handcuffs you in reimplementing
the method. In fact, the method can be changed to throw any subclass of
A, B or C without breaking compatibility. If you're designing a method
that has to remain compatible (one in a widely used library, like the .NET
Framework) A, B and C should be categories of exception like IOException,
not the specific IO exceptions that can be thrown in the first
implementation.


How much does it really help you to know that the method throws some kind of
IOException without telling you which ones?

Also, for versioning, consider the case where a method had previously been
written to handle FileStream I/O and therefore had a throws IOException but
now wants to be able to get data from a network as well. The FileStream
parameter is changed to Stream, and the throws clause is changed to include
NetworkException, and you've got a versioning problem.
One advantage of checked exceptions is that it allows the documentation to
know which exceptions are thrown. Compare the JDK Javadoc with the .NET
API documentation. You'll see how much better the Javadoc is about
showing which exceptions are thrown and why.


Should ease of automatic documentation be a reason to implement a language
feature like this? An <exception> tag in Xml comments in C# solves this
problem without constraining the language.

John Saunders
Nov 16 '05 #6

P: n/a
I believe that checked exceptions of some kind are a good idea; I'm not
sure that Java got it right, and C#/.NET didn't get it right by getting
rid of them entirely. Java feels slightly cumbersome because of them,
and C# sometimes feels like driving without a seatbelt due to the lack
of them. The first language/platform which gets exception handling
really "right" will be interesting...


Yet...somehow I think you'll still find a large percentage of people who
like the java or C# way...

I wonder what right is.
Nov 16 '05 #7

P: n/a

"John Saunders" <johnwsaundersiii at hotmail.com> wrote in message
news:uY**************@TK2MSFTNGP14.phx.gbl...
"Mike Schilling" <ms*************@hotmail.com> wrote in message
news:eZ**************@TK2MSFTNGP15.phx.gbl...

"Richard Blewett [DevelopMentor]" <ri******@NOSPAMdevelop.com> wrote in
message news:uG**************@TK2MSFTNGP10.phx.gbl...
Nope C# doesn't support checked exceptions. Heres a transcript of Bruce
Eckle and Anders Hejlsberg discussing why they are not in C#.

http://www.artima.com/intv/handcuffs.html
I find the "versioning" argument here weak, for two reasons:

The implication is that a method

void M() throws A, B, C

throws precisely A, B and C, and that this handcuffs you in
reimplementing the method. In fact, the method can be changed to throw
any subclass of A, B or C without breaking compatibility. If you're
designing a method that has to remain compatible (one in a widely used
library, like the .NET Framework) A, B and C should be categories of
exception like IOException, not the specific IO exceptions that can be
thrown in the first implementation.


How much does it really help you to know that the method throws some kind
of IOException without telling you which ones?


Quite a bit.

public void close() throw IOException;

Java reminds you that a close does I/O that can fail (in particular buffer
flushing.) C# doesn't. Any guesses how much C# code handles failures in
Close() ?

Also, for versioning, consider the case where a method had previously been
written to handle FileStream I/O and therefore had a throws IOException
but now wants to be able to get data from a network as well. The
FileStream parameter is changed to Stream, and the throws clause is
changed to include NetworkException, and you've got a versioning problem.
Not when Network exception is a subclass of IOException, which logically it
will be.
One advantage of checked exceptions is that it allows the documentation
to know which exceptions are thrown. Compare the JDK Javadoc with the
.NET API documentation. You'll see how much better the Javadoc is about
showing which exceptions are thrown and why.


Should ease of automatic documentation be a reason to implement a language
feature like this? An <exception> tag in Xml comments in C# solves this
problem without constraining the language.

But the exception tags don't get put in C# methods, they do get put into the
Java ones.
Nov 16 '05 #8

P: n/a
"Mike Schilling" <ms*************@hotmail.com> wrote in message
news:eL**************@tk2msftngp13.phx.gbl...

"John Saunders" <johnwsaundersiii at hotmail.com> wrote in message
news:uY**************@TK2MSFTNGP14.phx.gbl...
"Mike Schilling" <ms*************@hotmail.com> wrote in message
news:eZ**************@TK2MSFTNGP15.phx.gbl...

"Richard Blewett [DevelopMentor]" <ri******@NOSPAMdevelop.com> wrote in
message news:uG**************@TK2MSFTNGP10.phx.gbl...
Nope C# doesn't support checked exceptions. Heres a transcript of Bruce
Eckle and Anders Hejlsberg discussing why they are not in C#.

http://www.artima.com/intv/handcuffs.html

I find the "versioning" argument here weak, for two reasons:

The implication is that a method

void M() throws A, B, C

throws precisely A, B and C, and that this handcuffs you in
reimplementing the method. In fact, the method can be changed to throw
any subclass of A, B or C without breaking compatibility. If you're
designing a method that has to remain compatible (one in a widely used
library, like the .NET Framework) A, B and C should be categories of
exception like IOException, not the specific IO exceptions that can be
thrown in the first implementation.


How much does it really help you to know that the method throws some kind
of IOException without telling you which ones?


Quite a bit.

public void close() throw IOException;

Java reminds you that a close does I/O that can fail (in particular buffer
flushing.) C# doesn't. Any guesses how much C# code handles failures in
Close() ?


All of mine does. ;-)

Look, _anything_ can fail. It does you little good to know that Close() can
throw IOException. How much does that help you over "throws Exception"?

Also, for versioning, consider the case where a method had previously
been written to handle FileStream I/O and therefore had a throws
IOException but now wants to be able to get data from a network as well.
The FileStream parameter is changed to Stream, and the throws clause is
changed to include NetworkException, and you've got a versioning problem.


Not when Network exception is a subclass of IOException, which logically
it will be.


Why? It isn't in .NET. Don't know about the Java case. If network exceptions
are subclasses of IOException, then tell me what is _not_ a subclass of
IOException (aside from Exception).
One advantage of checked exceptions is that it allows the documentation
to know which exceptions are thrown. Compare the JDK Javadoc with the
.NET API documentation. You'll see how much better the Javadoc is about
showing which exceptions are thrown and why.


Should ease of automatic documentation be a reason to implement a
language feature like this? An <exception> tag in Xml comments in C#
solves this problem without constraining the language.

But the exception tags don't get put in C# methods, they do get put into
the Java ones.


The exception tags get put in by developers who want to document what
exceptions are thrown, and it didn't take a language feature to get that
done. And they're likely to be a lot more specific that "IOException".

John Saunders
Nov 16 '05 #9

P: n/a

"John Saunders" <johnwsaundersiii at hotmail.com> wrote in message
news:eE**************@TK2MSFTNGP14.phx.gbl...
Java reminds you that a close does I/O that can fail (in particular
buffer flushing.) C# doesn't. Any guesses how much C# code handles
failures in Close() ?
All of mine does. ;-)


Good for you. Mine too. A lot doesn't, just in as C, a lot didn't check
the return status from close() or fclose().
Why? It isn't in .NET. Don't know about the Java case. If network
exceptions are subclasses of IOException, then tell me what is _not_ a
subclass of IOException (aside from Exception).

Illegal argument?
Invalid state?
Concurrent modification?
No such class/method/field?
Access not allowed?
etc.


One advantage of checked exceptions is that it allows the documentation
to know which exceptions are thrown. Compare the JDK Javadoc with the
.NET API documentation. You'll see how much better the Javadoc is
about showing which exceptions are thrown and why.

Should ease of automatic documentation be a reason to implement a
language feature like this? An <exception> tag in Xml comments in C#
solves this problem without constraining the language.

But the exception tags don't get put in C# methods, they do get put into
the Java ones.


The exception tags get put in by developers who want to document what
exceptions are thrown, and it didn't take a language feature to get that
done. And they're likely to be a lot more specific that "IOException".


Then why is the .NET framework documentation so poor in documenting
exceptions compared to the JDK docs?
Nov 16 '05 #10

P: n/a
"Mike Schilling" <ms*************@hotmail.com> wrote in message
news:uQ**************@TK2MSFTNGP14.phx.gbl...

"John Saunders" <johnwsaundersiii at hotmail.com> wrote in message
news:eE**************@TK2MSFTNGP14.phx.gbl...
Java reminds you that a close does I/O that can fail (in particular
buffer flushing.) C# doesn't. Any guesses how much C# code handles
failures in Close() ?


All of mine does. ;-)


Good for you. Mine too. A lot doesn't, just in as C, a lot didn't check
the return status from close() or fclose().
Why? It isn't in .NET. Don't know about the Java case. If network
exceptions are subclasses of IOException, then tell me what is _not_ a
subclass of IOException (aside from Exception).

Illegal argument?
Invalid state?
Concurrent modification?
No such class/method/field?
Access not allowed?
etc.


> One advantage of checked exceptions is that it allows the
> documentation to know which exceptions are thrown. Compare the JDK
> Javadoc with the .NET API documentation. You'll see how much better
> the Javadoc is about showing which exceptions are thrown and why.

Should ease of automatic documentation be a reason to implement a
language feature like this? An <exception> tag in Xml comments in C#
solves this problem without constraining the language.
But the exception tags don't get put in C# methods, they do get put into
the Java ones.


The exception tags get put in by developers who want to document what
exceptions are thrown, and it didn't take a language feature to get that
done. And they're likely to be a lot more specific that "IOException".


Then why is the .NET framework documentation so poor in documenting
exceptions compared to the JDK docs?


The JDK docs naturally document what's in the throws clauses. I'm not even
sure whether the .NET documentation comes from Xml comments in C# code.

John Saunders
Nov 16 '05 #11

P: n/a
Really, I wasn't going to comment on this holy-war, but I think I will
anyway.

INTRO
-----

Checked exceptions seems like a good idea at first, which is probably
why it's included in JAVA. Unfortunatly it has a few problems, owing
sub-typing and the variance of errors, which makes it tempting to
declare every method "throws Throwable". I will shortly discuss the
problem with current implementations of checked exceptions and then
propose a method which makes checked exceptions beneficial in the way
checked-exception proponents usually argue it is.

EXAMPLE
-------

Let's do an example, C# syntax (this is m*.p*.d*.l*.csharp :) with
checked exceptions as in Java.

/** Persist objects, allow retrieval by id */
interface ObjectStore {
int Store(Object);
Object Retrieve(int id);
}

Now for a specific implementation that uses a directory with files for
storage:
public class DiskObjectStore: ObjectStore {
string Directory;
Object Retrieve(int id) {
using ( Stream s =
File.Open(File.Combine(Directory, id.ToString()))) {
// fetch object
...
}
}
}

WHAT SHOULD WE DO WITH THE D***** EXCEPTION
-------------------------------------------
(chorus: WITH THE D***** EXCEPTION)

Obviously File.Open(...) can throw a FileNotFound exception, so should
we catch and discard that? probably not, since we would deprive the
caller of accurate information about what failed.

So, we have to change the declaration of Retrieve:

Object Retrieve(int id): throws FileNotFound {...}

But that doesn't match the interface, and the interface declaration has
to be expanded to include a "throws FileNotFound". This removes the
abstractness of the interface, so you might suggest: "every
implementation of ObjectStore must do some I/O, so we'll let it throw
IOException".

Cutting heels and clipping toes
-------------------------------

This ensnaring argument hides the fundamental problem: you declared the
interface to be implementation-independant in the first place. Even
worse many implementations might NEVER throw an IOException, for example
a test-implementation:

public class MemoryStorage: ObjectStore {
IDictionary objects = new HashTable();
Object Retrieve(int id) throws IOException {
return objects[id]; // cannot throw IOException
}
}

or they might throw a whole new type of exception:

int id_count = 0;
int Store(Object o) {
int id = ++id_count; // ignore concurrency problems for now, ok?
if ( id_count == 0 )
throw new OutOfNamespace(o);
else
objects[id] = o;
}

When it's NOT a feary-tale
--------------------------

In the real world, what you end up with is usually either a global
throws declaration in the interface (and on all the callers of the
interface methods):

Object Retrieve(int id): throws Exception();

Or (nervous ticks starts) every implementation doing:

try {
using ( Stream s =
File.Open(File.Combine(Directory, id.ToString()))) {
// fetch object
...
}
} catch ( Exception e ) {
// an error occured, lot's of info in e, let's throw it away
return null;
}

And a VERY confusing code-style (*mildly* better: Logging errors and
returning null's.)

This is what most JAVA programmers do, atleast in the code i've seen :)

Wrapping extinguish type
------------------------

The last (and worst) alternative (which unfortunatly is done in a lot of
places in .NET) is to wrap the exception:

try {
using ( Stream s =
File.Open(File.Combine(Directory, id.ToString()))) {
// fetch object
...
}
} catch ( Exception e ) {
throw new ObjectStoreException(e);
}

This prevents the caller from even catching on the actual type of
exception occuring, and thus robs him of a viable retry strategy (unless
he wants to traverse the .Inner's of exceptions looking for the real
problem. This would take HEAPS of code, especially if more than one
wrapping is done). It actually removes the whole point of having Types
exceptions :)

*** NOTE: .NET Delegate's do exception wrapping, making catch on a
delegate-invocation a VERY delicate thing to try.

So, while checked exceptions have some nice properties, they really are
tedious to work with when polymorphism is used, since they precisely
expose the implementation differences that you wished to ignore by using
polymorphism.

JAVA
----

Now, zooming in on JAVA: JAVA has excepted that having every exception
as checked is too tedious. In JAVA there are RuntimeException's that may
be thrown *without* declaration in throws statements, and we may even
declare such an exception ourselves, BUT the class heirarchy is used to
indicate whether an exception should be checked or not.

This is higly unfortunate, since it deprives the programmer of the
ability to decide seperatly from situation to situation how "important"
a specific type of exception is, whether it should be catched or not by
the caller.

PROPOSAL
--------

If it was possible to declare "throws" statements on functions and
require callers to either handle or declare the exceptions themselves
(no class-hierarchy spec. of what should be checked here), AND it was
possible to "uncheck" an exception, allowing the caller to knowingly
pass a previously checked exception from a function as unchecked, now
that WOULD be usefull.

It would allow us to write the interface from above in the way we
wanted, without any throws qualifier, but it would allow File.Open to
declare that a FileNotFoundException could reasonably occur and that the
caller should do something about it.

The resulting code would be something like (with a newly invented syntax
for "unchecking", could probably be MUCH ):

using ( Stream s =
uncheck(File.Open(File.Combine(Directory, id.ToString()))),
FileNotFound)
{
// fetch object
...
}

The "uncheck" generates no code, and no catch-handler, it simply
instructs the compiler that the programmer knows that the call to
File.Open may cause an exception, but that should be accepted at
runtime, rather the provably handled by the caller.

CONCLUSION
----------

In this way the intrusion of checked exceptions may be kept to a
tolerable level, and cheked exceptions declarations can be actually
utilized to indicate "hey mate, this might fail, and you better have
something up your sleeve if it does".

--
Helge
Nov 16 '05 #12

P: n/a
"Helge Jensen" <he**********@slog.dk> wrote in message
news:41**************@slog.dk...
Really, I wasn't going to comment on this holy-war, but I think I will
anyway.
Thanks for the comment, and thanks for bringing it out of .aspnet. I'll keep
it in the list for a while, for anyone following this there, but if this
goes on for long, I hope we can all agree that .aspnet time is over. :-)

....
*** NOTE: .NET Delegate's do exception wrapping, making catch on a
delegate-invocation a VERY delicate thing to try.
I was unaware of this. Could you provide some detail on this behavior?
PROPOSAL
--------

If it was possible to declare "throws" statements on functions and require
callers to either handle or declare the exceptions themselves (no
class-hierarchy spec. of what should be checked here), AND it was possible
to "uncheck" an exception, allowing the caller to knowingly pass a
previously checked exception from a function as unchecked, now that WOULD
be usefull.

It would allow us to write the interface from above in the way we wanted,
without any throws qualifier, but it would allow File.Open to declare that
a FileNotFoundException could reasonably occur and that the caller should
do something about it.


I have some question in general about this entire area. The fact is that,
when my code can handle an exception, I handle it. But when it doesn't have
anything useful to contribute to the processing of the exception, I get out
of the way and let my callers deal with it. Maybe the caller can handle the
exception, even though there's nothing useful I can do with it right now.

I _do_ sometimes wrap exceptions with something more application-specific.
For instance, I have a Login method for logging in to a web service. This
method will wrap a SoapException in a LoginFailedException. Presumably, my
caller called me in order to log in, and should be told that the login
failed. My Message says, "Can't log in as <username>", which is more useful
than "required header not supplied in call". If my caller thinks he knows
what to do about a SoapException, I supply it to him as the InnerException
property, but I don't decline to give him useful information on the off
chance that he really wanted to see that SoapException instead of my
LoginFailedException.

I assume that my callers are taking care of their IDisposable resources with
"using" blocks or the equivalent. I assume they're backing out of anything
else that needs backing out of with "finally" blocks. And I assume they have
a strategy for what to do with exceptions that nobody has been able to
handle. Maybe they've got a try-catch block around their message loop, or,
perhaps they do like I often do in Windows Forms applications, and place
their entire event handler in a try-catch block. Maybe my ultimate caller is
an ASP.NET application which handles all unhandled exceptions in Global.asax
and needs to e-mail exception details to the support group and write them to
the Windows event log?

In any case, none of those questions should have anything to do with me as a
class library designer. I should handle the exceptions if I can do so
usefully, I should wrap the exceptions if I want to make them more relevant
to my direct caller, and otherwise, I should stay out of the way!

And, BTW, I should document what exceptions I throw so that my callers can
think about their exception handling strategies ahead of time. In my
documentation, I should not only indicate which exceptions I throw (which is
what a "throws" clause does in Java), but I should also indicate _why_ the
exception might be thrown and perhaps give guidance as to what a caller
might do about it:

John Saunders
Nov 16 '05 #13

P: n/a

"John Saunders" <johnwsaundersiii at hotmail.com> wrote in message
news:eG**************@TK2MSFTNGP09.phx.gbl...
"Mike Schilling" <ms*************@hotmail.com> wrote in message .. And they're likely to be a lot more specific that "IOException".

Then why is the .NET framework documentation so poor in documenting
exceptions compared to the JDK docs?


The JDK docs naturally document what's in the throws clauses.

Exactly my point.
I'm not even sure whether the .NET documentation comes from Xml comments in
C# code.

Nov 16 '05 #14

P: n/a

"Helge Jensen" <he**********@slog.dk> wrote in message
news:41**************@slog.dk...
Really, I wasn't going to comment on this holy-war, but I think I will
anyway.

INTRO
-----

Checked exceptions seems like a good idea at first, which is probably why
it's included in JAVA. Unfortunatly it has a few problems, owing
sub-typing and the variance of errors, which makes it tempting to declare
every method "throws Throwable". I will shortly discuss the problem with
current implementations of checked exceptions and then propose a method
which makes checked exceptions beneficial in the way checked-exception
proponents usually argue it is.

EXAMPLE
-------

Let's do an example, C# syntax (this is m*.p*.d*.l*.csharp :) with checked
exceptions as in Java.

/** Persist objects, allow retrieval by id */
interface ObjectStore {
int Store(Object);
Object Retrieve(int id);
}
No exceptions defined at this level? These methods can never fail?

Let's start by thinking about how Retrieve, for example, can fail.

1. The id can fail to refer.
2. The object store in use was never initialized.
3. An error occurred fetching (e.g. deserializing) this object.

That's not exhaustive, but it's a start.

Thus:

public Object Retrieve(int id) throws NoSuchObjectException,
StoreNotInitializedException, RetrieveFailedException
Now for a specific implementation that uses a directory with files for
storage:
public class DiskObjectStore: ObjectStore {
string Directory;
Object Retrieve(int id) {
using ( Stream s =
File.Open(File.Combine(Directory, id.ToString()))) {
// fetch object
...
}
}
}

WHAT SHOULD WE DO WITH THE D***** EXCEPTION


Is this supposed to be hard?

catch(IOException ex)
{
throw new NoSuchObjectException("" + id + " is not a valid object
identifier", ex);
}

Nov 16 '05 #15

P: n/a

Thanks for all your comments. Helge comments and Richard's link are very
helpful.

C.P. [No MCSD]
"Helge Jensen" <he**********@slog.dk> wrote in message
news:41**************@slog.dk...
Really, I wasn't going to comment on this holy-war, but I think I will
anyway.

INTRO
-----

Checked exceptions seems like a good idea at first, which is probably
why it's included in JAVA. Unfortunatly it has a few problems, owing
sub-typing and the variance of errors, which makes it tempting to
declare every method "throws Throwable". I will shortly discuss the
problem with current implementations of checked exceptions and then
propose a method which makes checked exceptions beneficial in the way
checked-exception proponents usually argue it is.

EXAMPLE
-------

Let's do an example, C# syntax (this is m*.p*.d*.l*.csharp :) with
checked exceptions as in Java.

/** Persist objects, allow retrieval by id */
interface ObjectStore {
int Store(Object);
Object Retrieve(int id);
}

Now for a specific implementation that uses a directory with files for
storage:
public class DiskObjectStore: ObjectStore {
string Directory;
Object Retrieve(int id) {
using ( Stream s =
File.Open(File.Combine(Directory, id.ToString()))) {
// fetch object
...
}
}
}

WHAT SHOULD WE DO WITH THE D***** EXCEPTION
-------------------------------------------
(chorus: WITH THE D***** EXCEPTION)

Obviously File.Open(...) can throw a FileNotFound exception, so should
we catch and discard that? probably not, since we would deprive the
caller of accurate information about what failed.

So, we have to change the declaration of Retrieve:

Object Retrieve(int id): throws FileNotFound {...}

But that doesn't match the interface, and the interface declaration has
to be expanded to include a "throws FileNotFound". This removes the
abstractness of the interface, so you might suggest: "every
implementation of ObjectStore must do some I/O, so we'll let it throw
IOException".

Cutting heels and clipping toes
-------------------------------

This ensnaring argument hides the fundamental problem: you declared the
interface to be implementation-independant in the first place. Even
worse many implementations might NEVER throw an IOException, for example
a test-implementation:

public class MemoryStorage: ObjectStore {
IDictionary objects = new HashTable();
Object Retrieve(int id) throws IOException {
return objects[id]; // cannot throw IOException
}
}

or they might throw a whole new type of exception:

int id_count = 0;
int Store(Object o) {
int id = ++id_count; // ignore concurrency problems for now, ok?
if ( id_count == 0 )
throw new OutOfNamespace(o);
else
objects[id] = o;
}

When it's NOT a feary-tale
--------------------------

In the real world, what you end up with is usually either a global
throws declaration in the interface (and on all the callers of the
interface methods):

Object Retrieve(int id): throws Exception();

Or (nervous ticks starts) every implementation doing:

try {
using ( Stream s =
File.Open(File.Combine(Directory, id.ToString()))) {
// fetch object
...
}
} catch ( Exception e ) {
// an error occured, lot's of info in e, let's throw it away
return null;
}

And a VERY confusing code-style (*mildly* better: Logging errors and
returning null's.)

This is what most JAVA programmers do, atleast in the code i've seen :)

Wrapping extinguish type
------------------------

The last (and worst) alternative (which unfortunatly is done in a lot of
places in .NET) is to wrap the exception:

try {
using ( Stream s =
File.Open(File.Combine(Directory, id.ToString()))) {
// fetch object
...
}
} catch ( Exception e ) {
throw new ObjectStoreException(e);
}

This prevents the caller from even catching on the actual type of
exception occuring, and thus robs him of a viable retry strategy (unless
he wants to traverse the .Inner's of exceptions looking for the real
problem. This would take HEAPS of code, especially if more than one
wrapping is done). It actually removes the whole point of having Types
exceptions :)

*** NOTE: .NET Delegate's do exception wrapping, making catch on a
delegate-invocation a VERY delicate thing to try.

So, while checked exceptions have some nice properties, they really are
tedious to work with when polymorphism is used, since they precisely
expose the implementation differences that you wished to ignore by using
polymorphism.

JAVA
----

Now, zooming in on JAVA: JAVA has excepted that having every exception
as checked is too tedious. In JAVA there are RuntimeException's that may
be thrown *without* declaration in throws statements, and we may even
declare such an exception ourselves, BUT the class heirarchy is used to
indicate whether an exception should be checked or not.

This is higly unfortunate, since it deprives the programmer of the
ability to decide seperatly from situation to situation how "important"
a specific type of exception is, whether it should be catched or not by
the caller.

PROPOSAL
--------

If it was possible to declare "throws" statements on functions and
require callers to either handle or declare the exceptions themselves
(no class-hierarchy spec. of what should be checked here), AND it was
possible to "uncheck" an exception, allowing the caller to knowingly
pass a previously checked exception from a function as unchecked, now
that WOULD be usefull.

It would allow us to write the interface from above in the way we
wanted, without any throws qualifier, but it would allow File.Open to
declare that a FileNotFoundException could reasonably occur and that the
caller should do something about it.

The resulting code would be something like (with a newly invented syntax
for "unchecking", could probably be MUCH ):

using ( Stream s =
uncheck(File.Open(File.Combine(Directory, id.ToString()))),
FileNotFound)
{
// fetch object
...
}

The "uncheck" generates no code, and no catch-handler, it simply
instructs the compiler that the programmer knows that the call to
File.Open may cause an exception, but that should be accepted at
runtime, rather the provably handled by the caller.

CONCLUSION
----------

In this way the intrusion of checked exceptions may be kept to a
tolerable level, and cheked exceptions declarations can be actually
utilized to indicate "hey mate, this might fail, and you better have
something up your sleeve if it does".

--
Helge

Nov 16 '05 #16

P: n/a
"Mike Schilling" <ms*************@hotmail.com> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...

"John Saunders" <johnwsaundersiii at hotmail.com> wrote in message
news:eG**************@TK2MSFTNGP09.phx.gbl...
"Mike Schilling" <ms*************@hotmail.com> wrote in message

. And they're likely to be a lot more specific that "IOException".

Then why is the .NET framework documentation so poor in documenting
exceptions compared to the JDK docs?


The JDK docs naturally document what's in the throws clauses.

Exactly my point.


And my point is that one should hire tech writers to write documentation,
not compiler designers.

John Saunders
Nov 16 '05 #17

This discussion thread is closed

Replies have been disabled for this discussion.