Roslyn: Proposal: Lenient Checked exceptions with warnings, without type

Created on 21 Dec 2016  路  8Comments  路  Source: dotnet/roslyn

Although, checked exception was intentionally left out while designing C# and .net, can this be implemented now in a non-breaking way? I propose to-

  • Follow proposed strict null checking and warn instead of raising error if declared exception not handled.
  • Follow Midori and add only throws with the method signature instead of adding full type of the exception.

And, all about error handling, specially pros and cons of different error handling models has been discussed by Joe Duffy in this blog post-
http://joeduffyblog.com/2016/02/07/the-error-model/#where-are-we

Area-Language Design Discussion Feature Request Language-C#

Most helpful comment

1st, it needs to differentiate program error exceptions (invalid argument, index out of range, etc.) from runtime exceptions. As Joe Duffy already mentioned, normal developers do not really care about the difference. Is it really right choice to teach developers the difference and enforce it?

2nd, unlike Midori which has a dedicated scope, C# has a much wider usage, thus much more runtime exception types. The frequency that throws need to appear will be much higher. I'd say, if the frequency is low, simple throws tag will be good enough. But when the frequency is high, it is no longer that useful but more of noise which developers use to shut up the warning.

All 8 comments

This could be implemented in a non-breaking fashion by using Warning Waves. A checked exception wave could be added to the compiler at some stage.

1st, it needs to differentiate program error exceptions (invalid argument, index out of range, etc.) from runtime exceptions. As Joe Duffy already mentioned, normal developers do not really care about the difference. Is it really right choice to teach developers the difference and enforce it?

2nd, unlike Midori which has a dedicated scope, C# has a much wider usage, thus much more runtime exception types. The frequency that throws need to appear will be much higher. I'd say, if the frequency is low, simple throws tag will be good enough. But when the frequency is high, it is no longer that useful but more of noise which developers use to shut up the warning.

I agree that there should be some sort of classification and option for both checked and unchecked exceptions. Even Java, notoriously known for checked exceptions, does also have unchecked exceptions with RuntimeException class.

Checked exceptions are bad, exceptions are and should only be caught at an application level for developers to easily debug and find out root of an exception. For this part, we mostly never catch an exception in every method, we let the exception rise up to the caller.

This enforces us to declare exceptions, which is not only time consuming but totally useless as sometimes it does not conform to overriding methods and forces us to swallow an exception.

Bigger problem with Java's checked exception is when you are implementing a method which did not declare exceptions. You are forced to swallow the exception.

I know you are talking about warnings, but eventually you will end up with lots of warnings which eventually can be avoided by writing good amount of unit tests.

This enforces us to declare exceptions

No it doesn't. If you read the proposal carefully:

  • Follow Midori and add only throws with the method signature instead of adding full type of the exception.

It specifically avoids the pitfall of having to declare all the different exceptions your method could throw, only indicating "there are some exceptions this method can be expected to throw".

@neurospeech As Joe Duffy mentioned in the linked article, http://joeduffyblog.com/2016/02/07/the-error-model/#bugs-arent-recoverable-errors , there are bugs and there are recoverable errors. And exceptions should only be used for the latter. The challenge here is, as @qrli mentioned, C# has been historically using exceptions for both cases. So, learning and teaching to distinguishing between the two is a challenge. But I think, .net standard library is the place to start, with the help of non-breaking warning waves #1580 . And when nullability checking (and probably ranged types as Joe mentioned) lands to C#, the bugs are mostly gone. End developers then will just have to worry about recoverable bugs aka exceptions.

As I am talking about warnings, which is used to warn for a probable bug, there is no enforcement. And adding throws should not change the methods signature in a way that causes mismatch with the overriding methods. I think, only real implementations should be able to add throws, not the declarations in interfaces and abstract classes. And, unit testing is totally orthogonal to this thing.

Actually, the way Java has implemented checked exceptions is a big pain for developers. But, checked exceptions are not evil all by themselves. They provides extra information to avoid bugs. When adding checked exception, one should look at Java to avoid the mistakes it has made.

Spotted this, quite coincidentally, just now regarding TDD or unit testing, what it can and cannot do-
http://softwareengineering.stackexchange.com/questions/331864/does-tdd-make-defensive-programming-redundant

Closing this now. Further discussion should happen in csharplang repo.

Was this page helpful?
0 / 5 - 0 ratings