Replies: 11 comments 89 replies
-
I believe checked exceptions are generally bad. I recommend reading this interesting discussion with Anders Hejlsberg explaining why C# does not have them. http://www.artima.com/intv/handcuffs.html |
Beta Was this translation helpful? Give feedback.
-
It is unlikely we'd reverse ourselves on such a longstanding and deep design issue. |
Beta Was this translation helpful? Give feedback.
-
You should also read http://joeduffyblog.com/2016/02/07/the-error-model/ It will give a wide view about error communication in general: checked exceptions, unchecked exceptions, error codes, fail fast and how it is done in other languages. It also present a different solution with contracts, which have a proposal in here #105 Worth reading! A lot of knowledge in one place. |
Beta Was this translation helpful? Give feedback.
-
I have to support the ticket author. When I read articles and comments arguing against checked exceptions, they remind me much of the arguments of dynamic typing vs static typing. When I call a method in C# it’s obvious what it’s return type will be. But I have no idea if it may raise an exception. So to be 100% sure I would need to put a try catch statement araound a lot of calls. Checked exception and static typing have a lot similarities. Pro
A good practise is to write code, which is easy to reason about it’s behaviour. I respect mr Heilsbergs opinion a lot, but C# was designed a long time ago and apparently a design goal was to make it easier for people switching to C#. That shouldn’t hinder us today to think about possibilities to make our code more expressive and therefore our work easier. And maybe also have a different opinion than a very smart person. PS: I remember the days when (also smart) people where arguing against static typing and emphasising the benefits of dynamic typing. |
Beta Was this translation helpful? Give feedback.
-
Checked exceptions as they are implemented in a language like Java don't make API evolution difficult, they make it impossible. The exceptions are a part of the contract and it's impossible to add any others without breaking all existing consumers. So that forces implementers to group exceptions in weird ways, or just default to throwing everything as unchecked, which is insanely common. Forcing every consumer of every method to either catch/handle all of the possible exceptions or explicitly propagate them up doesn't scale. And the entire concept of checked exceptions breaks down very painfully when you start to program in a more functional manner. I think it's telling that nearly every other language on the JVM just ignores checked exceptions outright. If C# were to ever get something like checked exceptions I could only ever see them handled like NRTs. External metadata that can be used to drive analyzers which might warn, but never anything stricter. A much better solution would be DUs and |
Beta Was this translation helpful? Give feedback.
-
Most of the references about the Checked Exception in C# are really old, without considering the new methodologies and design patterns, and around 99% of them say that this functionality/feature/design is bad. On one hand, we want to have a clean and reliable code, and On another hand, we say the maintenance of the code will be hard using Checked Exception. I believe the Checked Exception is good, especially when we are working on a class library as an external module for other systems. Each application that wants to use the class library, should know about the possible exceptions that may arise from the methods in our class library and handle them in the right way without needing trial and error. It is most useful when we want to write a unit test for our method, and there we can handle all possible exceptions with less concern about the runtime exceptions.
For the first case, it is really easy and the users don't need to do anything, but they can remove the unwanted handled exceptions if they want. Another issue mentioned in the articles against Checked Exception is that developers will use a general exception handler to wrap all checked exceptions in one place, and it will make them useless. If we want to worry about whether the developer will follow the structure, then why do we have this amount of design patterns? The developer who doesn't care about the structure, won't follow the design patterns too. Then it's totally up to the developer how to deal with this feature. He/She can handle it in the right way to get a better result or can omit the exceptions by wrapping all of them in one general try-catch. As the final word, to handle the versionability issue and decrease its defects on the client's codes, we can use different severities for each checked exception. E.g. we can use severities like Information, Warning, Error, and Fatal, and the client will have a better vision about how to deal with each exception. You can read my article about the Checked Exception here: and the repository to the Checked Exception extension on C# using Roslyn |
Beta Was this translation helpful? Give feedback.
-
I like this idea !! I discussed it long time ago, but all team members said me the same as they said to you ... The issue is that specifying exactly exception will not make code hard to maintain ... but all team members do not understand that Checked exception could be implemented like this: public class FileUtils
{
public void Write(string content)
throws // Said that this function just throw some exception
{ ...
}
public void WriteGeneric<T>(string content)
throws // Said that this function just throw some exception
where T: class {
...
}
} In such case it could add support for error if user forgot to handle all error, it will feels like Rust (errors), Swift (errors), Java (checked exceptions) ... |
Beta Was this translation helpful? Give feedback.
-
If possible exceptions is unchecked, then nobody can tell whether a method throws exceptions, so any method caller should initialize their local variable use |
Beta Was this translation helpful? Give feedback.
-
The real problem is not Checked Exceptions, but actually the try-catch pattern in the first place. Or to express it somewhat stronger:
But the real solution is actually the way how a language like Rust solves it. making success or failure state part of the return type of a method, using a Result<T, E> type, based on the underlying concept of so called discriminated unions (but note Rust calls them enum). This however is basically too late for C#. I am aware of that. |
Beta Was this translation helpful? Give feedback.
-
The advantage of checked exceptions is that thrown exceptions are part of the API, so you force callers to acknowledge it (either by handling or make it part of the caller method API). This helps prevent a lot of errors in code, but the way it's implemented in Java is not the best. Ideally, the compiler would implicitly detect and declare for you the exact
// this flag is implied by default if absent
#exceptions public
...
// explicit `throw ...;` statements are always in API automatically
// with `may not throw`, no additional exceptions can bubble up
// this disallows even unhandled exceptions in code itself, like null ref, out of range, class cast, etc.
// as well as exceptions that may be thrown from method calls, as per their API
void f() may not throw { ... }
// allow only these additional exceptions to implicit bubble up
void f() may throw A or B or ... { ... }
// allow any exception to bubble up; `A|B|...` is implicitly auto-filled by compiler and is part of the API
// when you hover an `f()` call in IDE, it shows the specific types of exceptions it may throw
// as if it had been declared explicitly in the function signature
void f() may throw { ... }
// non-publicly visible: implies `may throw` by default; compiler auto-fills API
internal void f() { ... }
// visible outside dll: implies `may not throw` by default;
// coder must handle bubbling exceptions, or declare them to ensure public API is correct
public void f() { ... } With // implies `may not throw` on any accessibility
// coder must always define bubbling exceptions (either explicitly per-exception, or with a `may throw`)
internal void f() { ... } With // exception is unspecified in public API,
// so if this dll is referenced by another project in a checked exception context,
// it assumes it `may throw Exception`
public void f() { ... } Of course, the list of exceptions in the API never includes unforeseeable crashing errors that might happen, like stack overflow not thrown by user code, etc., since those aren't expected to be caught. So, with this proposal, you'd get checked exceptions, but by default you don't even need to worry about adding |
Beta Was this translation helpful? Give feedback.
-
The general motivation is to avoid exceptions, and only face them during prototyping where you're probably mishandling an API, or entering some dark documentation zones. This sounds utopic, but checked exceptions wouldn't truly add much value. The XML documentation containing the exceptions that may be thrown does a good enough job, except if you're not using Rider. Unfortunately as of the time of writing, VS doesn't seem to respect exception tags in members much, failing to show the description of the specific exception. Overall, in the deployed product, you should avoid exceptions being thrown as much as possible, and design your API in an exception-free manner by offering types wrapping potential erroneous cases, or using The takeaway is, with this feature you gain value by not following better architectural practices. By notifying the user about the types of exceptions to expect, you're telling them that they must play around funky exceptions when all they want is to use your API, and your API should fail to work when something's not right. |
Beta Was this translation helpful? Give feedback.
-
What about Checked Exceptions in C# like Java?
I think it would be helpful to expect all behaviors of the method/object.
It will enforce that every method who calls FileUtils.Write should do it within a try..catch.. statement.
Beta Was this translation helpful? Give feedback.
All reactions