Exception handling in .NET
-
Hi all, I've recently had to work on a .NET web application. Now, although I've been familiar with .NET for approximately a year now, I'm primarily a Java developer. And while I think .NET is a great idea, there is one thing I don't quite understand about it -- the way exceptions are handled. In particular, I'm dissapointed by the lack of checked exceptions. A method does not need to declare that it may throw an exception, making it harder to manage the propagation of exceptions in your programs. Perhaps a simple example to demonstrate... Java:
// Read in a single line from the specified file and return it static void myReadLine(String filename) throws IOException { BufferedReader reader = new BufferedReader(new FileReader(filename)); return reader.readLine(); }
C#:// Read in a single line from the specified file and return it static void MyReadLine(string filename) { StreamReader reader = new StreamReader(filename); return reader.readLine(); }
It's pretty obvious what both methods are doing, and that they are doing it in pretty much the same way. The main difference is in how those methods can now be used. In C#.NET, you can call MyReadLine() from anywhere in your code and everything will happily compile. If things go wrong and an System.IOException is thrown in that method, then unless you've done your homework and surrounded the call to MyReadLine() with a try-catch block, your application will crash. With a pretty stack trace printed on the screen. Ungracefully. In Java, the code will not even compile unless you are explicitly catching that exception when calling myReadLine(). An IOException is a checked exception in Java -- meaning that if it's ever thrown, it must be caught somewhere in your code. Other exceptions, such as, say NullPointerException, are run-time exceptions and do not have to be explicitly caught (although sometimes it's not a bad idea to do so). In .NET, it seems, all exceptions are considered run-time. Even if you happened to know that StreamReader.ReadLine() throws an exception, there's a fair chance that some methods in your code could throw exceptions without you even knowing it. And if they can, then they will -- at the worst possible time, naturally. So your options are either keep your fingers crossed, or trawl through the documentation, checking for possible exceptions for each method your code is calling. Neither option is particularly appealing. Nor is catching the general Syst -
Hi all, I've recently had to work on a .NET web application. Now, although I've been familiar with .NET for approximately a year now, I'm primarily a Java developer. And while I think .NET is a great idea, there is one thing I don't quite understand about it -- the way exceptions are handled. In particular, I'm dissapointed by the lack of checked exceptions. A method does not need to declare that it may throw an exception, making it harder to manage the propagation of exceptions in your programs. Perhaps a simple example to demonstrate... Java:
// Read in a single line from the specified file and return it static void myReadLine(String filename) throws IOException { BufferedReader reader = new BufferedReader(new FileReader(filename)); return reader.readLine(); }
C#:// Read in a single line from the specified file and return it static void MyReadLine(string filename) { StreamReader reader = new StreamReader(filename); return reader.readLine(); }
It's pretty obvious what both methods are doing, and that they are doing it in pretty much the same way. The main difference is in how those methods can now be used. In C#.NET, you can call MyReadLine() from anywhere in your code and everything will happily compile. If things go wrong and an System.IOException is thrown in that method, then unless you've done your homework and surrounded the call to MyReadLine() with a try-catch block, your application will crash. With a pretty stack trace printed on the screen. Ungracefully. In Java, the code will not even compile unless you are explicitly catching that exception when calling myReadLine(). An IOException is a checked exception in Java -- meaning that if it's ever thrown, it must be caught somewhere in your code. Other exceptions, such as, say NullPointerException, are run-time exceptions and do not have to be explicitly caught (although sometimes it's not a bad idea to do so). In .NET, it seems, all exceptions are considered run-time. Even if you happened to know that StreamReader.ReadLine() throws an exception, there's a fair chance that some methods in your code could throw exceptions without you even knowing it. And if they can, then they will -- at the worst possible time, naturally. So your options are either keep your fingers crossed, or trawl through the documentation, checking for possible exceptions for each method your code is calling. Neither option is particularly appealing. Nor is catching the general SystYes there is a rationale behind this. Anders Hejlsberg (Turbo Pascal inventor, Delphi Lead Architect at Borland and now lead C# architect at MS) does explain why Javas checked exceptions are a nice concept but do break in big projects. http://www.artima.com/intv/handcuffs.html HTH, Alois Kraus
-
Hi all, I've recently had to work on a .NET web application. Now, although I've been familiar with .NET for approximately a year now, I'm primarily a Java developer. And while I think .NET is a great idea, there is one thing I don't quite understand about it -- the way exceptions are handled. In particular, I'm dissapointed by the lack of checked exceptions. A method does not need to declare that it may throw an exception, making it harder to manage the propagation of exceptions in your programs. Perhaps a simple example to demonstrate... Java:
// Read in a single line from the specified file and return it static void myReadLine(String filename) throws IOException { BufferedReader reader = new BufferedReader(new FileReader(filename)); return reader.readLine(); }
C#:// Read in a single line from the specified file and return it static void MyReadLine(string filename) { StreamReader reader = new StreamReader(filename); return reader.readLine(); }
It's pretty obvious what both methods are doing, and that they are doing it in pretty much the same way. The main difference is in how those methods can now be used. In C#.NET, you can call MyReadLine() from anywhere in your code and everything will happily compile. If things go wrong and an System.IOException is thrown in that method, then unless you've done your homework and surrounded the call to MyReadLine() with a try-catch block, your application will crash. With a pretty stack trace printed on the screen. Ungracefully. In Java, the code will not even compile unless you are explicitly catching that exception when calling myReadLine(). An IOException is a checked exception in Java -- meaning that if it's ever thrown, it must be caught somewhere in your code. Other exceptions, such as, say NullPointerException, are run-time exceptions and do not have to be explicitly caught (although sometimes it's not a bad idea to do so). In .NET, it seems, all exceptions are considered run-time. Even if you happened to know that StreamReader.ReadLine() throws an exception, there's a fair chance that some methods in your code could throw exceptions without you even knowing it. And if they can, then they will -- at the worst possible time, naturally. So your options are either keep your fingers crossed, or trawl through the documentation, checking for possible exceptions for each method your code is calling. Neither option is particularly appealing. Nor is catching the general Systmisha1983 wrote:
Can someone cast light on why are exceptions being handled this way in .NET? What are the advantages of treating all exceptions as run-time exceptions?
I would say that the checked exceptions in Java are still run-time exceptions (they get thrown at run-time, not at compile time) it is just that Java has the ability to explicitly declare which exceptions a method will throw as part of the method signature and the compiler just ensures they are either caught or become part of the signature of the calling method. I would say that the best discipline would be to ensure that, when you document the code, you define which exceptions a method will throw in the documentation. Intellisence in Visual Studio will read the XML documentation and generate appropriate tool tips while you are typing the method name to remind you that exceptions are thrown.
misha1983 wrote:
Is it something that you just learn to deal with as a .NET developer? How do you deal with it?
I've never really thought about it before. I was a C++ developer since 1992 before .NET came along and it never had checked exceptions either. In fact, in C++ you could throw any object you liked as an exception - which is probably a worse situation.
Scottish Developers events: * .NET debugging, tracing and instrumentation by Duncan Edwards Jones and Code Coverage in .NET by Craig Murphy * Developer Day Scotland: are you interested in speaking or attending? My: Website | Blog
-
Yes there is a rationale behind this. Anders Hejlsberg (Turbo Pascal inventor, Delphi Lead Architect at Borland and now lead C# architect at MS) does explain why Javas checked exceptions are a nice concept but do break in big projects. http://www.artima.com/intv/handcuffs.html HTH, Alois Kraus
Thank you. That is a very insightful article. It sheds a lot of light on the topic. The author makes points that are both relevant and valid. While I can't say I agree with all of them 100%, I can now see that there is indeed more than one way to skin a cat. Of particular interest is his approach to exception handling -- heavier use of the try-finally to free any acquired resources, and a centralised exception handler to actually deal with the exception. After reading that article, however, one particular paragraph bothered me:
From the article:
But that said, there's certainly tremendous value in knowing what exceptions can get thrown, and having some sort of tool that checks... But I think we can certainly do a lot with analysis tools that detect suspicious code, including uncaught exceptions, and points out those potential holes to you.
Now, I would like to know -- what publicly available tools like that are out there? Thanks. Cheers, Misha
-
Thank you. That is a very insightful article. It sheds a lot of light on the topic. The author makes points that are both relevant and valid. While I can't say I agree with all of them 100%, I can now see that there is indeed more than one way to skin a cat. Of particular interest is his approach to exception handling -- heavier use of the try-finally to free any acquired resources, and a centralised exception handler to actually deal with the exception. After reading that article, however, one particular paragraph bothered me:
From the article:
But that said, there's certainly tremendous value in knowing what exceptions can get thrown, and having some sort of tool that checks... But I think we can certainly do a lot with analysis tools that detect suspicious code, including uncaught exceptions, and points out those potential holes to you.
Now, I would like to know -- what publicly available tools like that are out there? Thanks. Cheers, Misha
misha1983 wrote:
what publicly available tools like that are out there?
I don't know of any. In fact I opened an FR with MS that would have the XML documentation created include any exceptions thrown inside the documented method, just to be sure that they get into the documentation.
-- modified at 10:33 Friday 14th July, 2006
-
misha1983 wrote:
Can someone cast light on why are exceptions being handled this way in .NET? What are the advantages of treating all exceptions as run-time exceptions?
I would say that the checked exceptions in Java are still run-time exceptions (they get thrown at run-time, not at compile time) it is just that Java has the ability to explicitly declare which exceptions a method will throw as part of the method signature and the compiler just ensures they are either caught or become part of the signature of the calling method. I would say that the best discipline would be to ensure that, when you document the code, you define which exceptions a method will throw in the documentation. Intellisence in Visual Studio will read the XML documentation and generate appropriate tool tips while you are typing the method name to remind you that exceptions are thrown.
misha1983 wrote:
Is it something that you just learn to deal with as a .NET developer? How do you deal with it?
I've never really thought about it before. I was a C++ developer since 1992 before .NET came along and it never had checked exceptions either. In fact, in C++ you could throw any object you liked as an exception - which is probably a worse situation.
Scottish Developers events: * .NET debugging, tracing and instrumentation by Duncan Edwards Jones and Code Coverage in .NET by Craig Murphy * Developer Day Scotland: are you interested in speaking or attending? My: Website | Blog
Colin Angus Mackay wrote:
it never had checked exceptions either.
C++ does have exception specifications with the same syntax. An exception specification in C++ provides a solution that can be used to list the exceptions a function may throw with the function declaration, but it does not force the caller to write code to catch the listed exceptions. I like the C++ way :-D Best, Jun
-
Thank you. That is a very insightful article. It sheds a lot of light on the topic. The author makes points that are both relevant and valid. While I can't say I agree with all of them 100%, I can now see that there is indeed more than one way to skin a cat. Of particular interest is his approach to exception handling -- heavier use of the try-finally to free any acquired resources, and a centralised exception handler to actually deal with the exception. After reading that article, however, one particular paragraph bothered me:
From the article:
But that said, there's certainly tremendous value in knowing what exceptions can get thrown, and having some sort of tool that checks... But I think we can certainly do a lot with analysis tools that detect suspicious code, including uncaught exceptions, and points out those potential holes to you.
Now, I would like to know -- what publicly available tools like that are out there? Thanks. Cheers, Misha
Static code analyzers like Reflector (it has a very good API but nearly no docu) can do this to a certain degree. You will never get 100% coverage since today software is plugable/configurable. There is no way to find out what module you did configure into you software. But for a good overview if some big holes are missed static code analyzers (FXCop should also be able to do this to a certain extent) they are surely useful. Yours, Alois Kraus
-
Hi all, I've recently had to work on a .NET web application. Now, although I've been familiar with .NET for approximately a year now, I'm primarily a Java developer. And while I think .NET is a great idea, there is one thing I don't quite understand about it -- the way exceptions are handled. In particular, I'm dissapointed by the lack of checked exceptions. A method does not need to declare that it may throw an exception, making it harder to manage the propagation of exceptions in your programs. Perhaps a simple example to demonstrate... Java:
// Read in a single line from the specified file and return it static void myReadLine(String filename) throws IOException { BufferedReader reader = new BufferedReader(new FileReader(filename)); return reader.readLine(); }
C#:// Read in a single line from the specified file and return it static void MyReadLine(string filename) { StreamReader reader = new StreamReader(filename); return reader.readLine(); }
It's pretty obvious what both methods are doing, and that they are doing it in pretty much the same way. The main difference is in how those methods can now be used. In C#.NET, you can call MyReadLine() from anywhere in your code and everything will happily compile. If things go wrong and an System.IOException is thrown in that method, then unless you've done your homework and surrounded the call to MyReadLine() with a try-catch block, your application will crash. With a pretty stack trace printed on the screen. Ungracefully. In Java, the code will not even compile unless you are explicitly catching that exception when calling myReadLine(). An IOException is a checked exception in Java -- meaning that if it's ever thrown, it must be caught somewhere in your code. Other exceptions, such as, say NullPointerException, are run-time exceptions and do not have to be explicitly caught (although sometimes it's not a bad idea to do so). In .NET, it seems, all exceptions are considered run-time. Even if you happened to know that StreamReader.ReadLine() throws an exception, there's a fair chance that some methods in your code could throw exceptions without you even knowing it. And if they can, then they will -- at the worst possible time, naturally. So your options are either keep your fingers crossed, or trawl through the documentation, checking for possible exceptions for each method your code is calling. Neither option is particularly appealing. Nor is catching the general SystApart from Anders's article at Artima there has been lots of discussion about this (and research) elsewhere on the web. The general consensus seems to be that checked exceptions seem like a good idea at first, but not such a good idea eventually! However, Spec#, MS's research language, which is a C# superset, does have checked exceptions and I think they provide a rationale for this, given the extra features of Spec#! So maybe some form of them may be rolled back into C#! Confusing, eh?:confused: Kevin