TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Why checked exceptions failed

108 pointsby rsaarelmalmost 2 years ago

23 comments

invalidnamealmost 2 years ago
My opinion is the exact opposite see <a href="https:&#x2F;&#x2F;debugagent.com&#x2F;everything-bad-in-java-is-good-for-you" rel="nofollow noreferrer">https:&#x2F;&#x2F;debugagent.com&#x2F;everything-bad-in-java-is-good-for-yo...</a><p>Checked exceptions are unpopular since no one likes responsibility. But they are great when used right. Calls that must have proper cleanup after them e.g. SQL, IO are checked. The fact that this must be communicated via interfaces is hugely important.<p>There are &quot;weird&quot; problems such as stream close() throwing a checked exception. That&#x27;s an API misbehavior that has a workaround thanks to try-with-resources.
评论 #36738605 未加载
评论 #36738245 未加载
评论 #36736437 未加载
评论 #36738903 未加载
评论 #36737921 未加载
jdm2212almost 2 years ago
Checked exceptions failed because 99 times out of 100 the exception is not recoverable, so the try&#x2F;catch block is just wasting everyone&#x27;s time. (In 7 years as a Java dev I can think of one time I wrote code that tried to recover from IOException instead of just making the caller retry.)<p>Even when the exceptions is theoretically recoverable, it has to get propagated up properly to the caller who should be handling recovery from it. But checked exceptions don&#x27;t propagate sanely through executors and across RPC calls, so good luck with that.
评论 #36741559 未加载
评论 #36741456 未加载
评论 #36741787 未加载
评论 #36741695 未加载
评论 #36741586 未加载
javajoshalmost 2 years ago
Checked exceptions are used to make up for Java&#x27;s inability to return more than one value, plus it&#x27;s inability to wrap two values without defining a new type. In other words, I think checked exceptions are basically a symptom of a lack of object literal syntax. This is in addition to their status as a &quot;cool language feature&quot; that is a siren song to new, bright programmers looking to spice up their designs. Exceptions are in general problematic (they move the program counter in a disjoint way - &quot;non-local change of control&quot; I think it&#x27;s called) so it makes this particular siren song doubly deadly.<p>It would probably be handy if someone wrote a pamphlet on &quot;Refactoring Exceptions&quot; to give teams the confidence to refactor exceptions out of their code. I&#x27;ll offer $20 to Martin Fowler to write such a thing.
评论 #36736803 未加载
评论 #36736819 未加载
评论 #36736529 未加载
o1y32almost 2 years ago
This is a very old topic. Insights from Anders Hejlsberg:<p><a href="https:&#x2F;&#x2F;www.artima.com&#x2F;articles&#x2F;the-trouble-with-checked-exceptions" rel="nofollow noreferrer">https:&#x2F;&#x2F;www.artima.com&#x2F;articles&#x2F;the-trouble-with-checked-exc...</a>
评论 #36740861 未加载
rcmealmost 2 years ago
The issue with all exceptions, and error handling in general, is that only very rarely is there actually recourse for an error. For instance, in an HTTP request handler, the vast majority of errors will end up as something like a 500. Checked exceptions are annoying because they make you explicitly handle an error when you likely already have a handler in place to handle <i>all</i> exceptions, checked or otherwise.
评论 #36740772 未加载
评论 #36736516 未加载
cubefoxalmost 2 years ago
While I broadly agree with this, the author doesn&#x27;t appear to go far enough himself.<p>&gt; Functional error handling, using Option and Result types, is rapidly becoming the standard operating procedure in essentially every language, because it relies on nothing but values and types. They are more of the same, and so they fit right into the existing language machinery.<p>I agree that Optional types are better than checked exceptions, but they are worse than union types. A function with the union return type String|Error (read: String or Error) is allowed to return another function with return type String. Similarly, a function which accepts the type String|Error as a parameter also accepts parameters of type String. With Option types this doesn&#x27;t work. Option&lt;String&gt; and String are incompatible types, so code has to be rewritten if the types change.<p>Personally, I would go so far as to say that union types should replace exceptions in general, checked or unchecked, as well as any implicit nullabiliy, which can be replaced with the explicit union type Foo|Null.<p>(Although some special syntax for handling Foo|Exception or Foo|Null is probably a good idea, as &quot;error&quot; and &quot;nothing&quot; are pretty general categories.)
评论 #36736528 未加载
评论 #36736593 未加载
评论 #36741781 未加载
评论 #36736668 未加载
breadwinneralmost 2 years ago
I have extensive experience in C# as well as Java. It is bizarre to suggest that checked exceptions have failed. It is unchecked exceptions that have failed. It is the biggest flaw of C#, in fact. Why?<p>As an example, I wrote some very good C# code, carefully tested it, made it work flawlessly, then suddenly it started crashing. What happened? Someone made a change in a function I was calling, and it started throwing a new exception. This would have caused a compile error in Java, not a crash.<p>The list of recoverable exceptions that can be thrown by a method should be part of the contract. It should be written down by the programmer, and enforced by the compiler. If not, then to avoid crashing you would have to catch the root Exception class, which everyone agrees is a bad idea.<p>More on checked vs unchecked exceptions here: <a href="https:&#x2F;&#x2F;forum.dlang.org&#x2F;thread&#x2F;hxhjcchsulqejwxywfbn@forum.dlang.org" rel="nofollow noreferrer">https:&#x2F;&#x2F;forum.dlang.org&#x2F;thread&#x2F;hxhjcchsulqejwxywfbn@forum.dl...</a>
评论 #36738129 未加载
评论 #36736439 未加载
评论 #36736816 未加载
评论 #36736567 未加载
评论 #36736375 未加载
评论 #36737575 未加载
评论 #36736538 未加载
评论 #36738881 未加载
评论 #36739157 未加载
评论 #36736416 未加载
评论 #36736513 未加载
DamonHDalmost 2 years ago
&quot;Nobody uses [checked exceptions&quot; in Java, this casually claims.<p>Oh dear. I have a slew of current counter examples on my machine, in GitHub, etc.<p>Either carelessly untrue or else annoying hypebole.<p>Made the rest very hard for me to read.
cvossalmost 2 years ago
&gt; Can I specify that implementations of foo can throw no, some, or all exceptions? What would it even mean to write something like throws *? Analogously, if I have a function that takes a method as an argument, like a callback, how do I specify what set of exceptions in can throw? Can I have generic “exception set parameters”?<p>&gt; Concretely, checked exceptions in Java failed because Java lacks “throwingness polymorphism”, if you will.<p>I don&#x27;t understand. <i>Every</i> &quot;missing feature&quot; the author asks for is, in fact, present in Java. The example below just about sums it up.<p><pre><code> @FunctionalInterface interface MyCallback&lt;X, Y, E extends Exception&gt; { Y apply (X x) throws E; } class A { &lt;X, Y, E extends Exception&gt; Y runCallback (MyCallback&lt;X, Y, E&gt; func, X x) throws E { return func.apply(x); } }</code></pre>
评论 #36741328 未加载
grumbelalmost 2 years ago
Little aside, but I feel a lot of the drama surrounding exception could have been solved with a little syntactic sugar making their handling easier. Something along the lines of Perl&#x27;s &quot;|| die(&quot;...&quot;)&quot; pattern would be a start (i.e. add some context and rethrow).<p>In C++ I find it quite infuriating that try{} opens up a new lexical scope, which means you can&#x27;t construct something, check for errors and move on, since the act of adding a try{} means you&#x27;d call the destructor of the thing you just constructed. Meanwhile surrounding a whole block of code with a try{} means you no longer can tell where the exception came from.
评论 #36738990 未加载
评论 #36736603 未加载
评论 #36737710 未加载
TrianguloYalmost 2 years ago
As others have mentioned, an interface is a contract and any possible exception that may be thrown needs to be explicitly defined, that&#x27;s why checked exceptions exists.<p>However, there is an exception (pun intended) to this: inline lambdas. You can use lambdas as variables, pass them as parameters, etc. And it makes sense for them to retain the interface if needed, but (at least on java) when you are doing a .map(v-&gt;parseInt(v)) checked exceptions can&#x27;t escape the lambda, and that&#x27;s probably the worst problem of java lambdas.<p>You can avoid this with custom interfaces where the exception is a generic parameter, but sadly native ones aren&#x27;t defined like this (yes, exceptions that a function throws can also be defined with generics, and the compiler will automatically use the more restrictive of the lambda code! )
tethaalmost 2 years ago
Yeah. The thing is, I like the idea of checked exceptions. You could go ahead and define a number of error situations or error kinds and annotate methods with these checked exceptions to force applications to handle these errors. Like, you have a Database.query function and it might throw different exceptions - ConnectionInterrupted, QueryPreparationFailed, QueryFailed, TransactionCancelled. And then you could catch specific error kinds and react differently on those - retry for interrupted connections, cancel on query errors.<p>This however runs into issues. One really annoying one: Checked exceptions are part of your API. If you forget an error condition and want to introduce a new exception for that, well guess what, that&#x27;s a breaking API change. There is no easy way to evolve an API with checked exceptions, because changing them requires new major versions, because it prevents code from compiling.<p>On top, if you want to encapsulate your API properly, you end up with a lot of boilerplate. Once you&#x27;re using a library, and that library has checked exceptions, you either have to base your own public API on the API of that library - meaning you can never replace it - or you have to start wrapping all manner of errors into your own checked exceptions. I&#x27;ve kinda done it as an experiment some time ago, but that just ends up with so many exception types and so much error wrapping it&#x27;s kinda ridiculous.<p>And then you end up with the sad truth on top to be honest: Most error checking is rather brute and clumsy. In most cases, I just let exceptions bubble up because my intermediate function can&#x27;t really do anything about it. As a distant second, you catch all errors, shove them in some kind of error reporting, reset the system and continue trucking. As a somewhat similar third, I dissect errors in CLI tools to create some useful error messages. And only them I might start caring about some specific errors, but that&#x27;s pretty rare if you&#x27;re just running some REST-based business logic.<p>All in all, it&#x27;s a good idea, but the implementation results in a lot of API churn or boilerplate for something that&#x27;s not used much in general.
评论 #36738173 未加载
mkleczekalmost 2 years ago
Checked exceptions failed in Java because they don&#x27;t play well with parametric polymorphism. Union types might help (exception list declaration is actually a union type) but I don&#x27;t think it would succeed anyway as it is not general enough.<p>Handling effects and effect polymorphism in programming languages is an active area of research and there are some new languages that try to approach the problem (ie. Koka).<p>Haskell has several effect libraries (effectful, cleff, eff, polysemy) that look quite nice.<p>Idris with its dependent types allows precise definition of effects in function signatures.
评论 #36738733 未加载
redeemanalmost 2 years ago
&gt; Can I specify that implementations of foo can throw no, some, or all exceptions?<p>just because theres the possibility of a throw in the signature, does not mean it has to be done in a concrete implementation, and if implementations are really to be exchangable, it has to be handled in case implementation changes.<p>&gt; What would it even mean to write something like throws *?<p>Roughly similar to &quot;throws Exception&quot; or &quot;throws Throwable&quot; - that it may throw whatever you have under the sun?<p>&gt; Concretely, checked exceptions in Java failed because Java lacks “throwingness polymorphism”, if you will.<p>it does allow for extending exceptions, so an interface can define some exceptions that are basic, and implementations can then choose to extend those to provide MORE detail if needed.<p>&gt; Was Java wrong to add checked exceptions? No. They took a risk and it didn’t pay off.<p>Uhm.... Im gonna go ahead and use some other opinion on this
评论 #36736321 未加载
necovekalmost 2 years ago
I am surprised an even more obvious interface definition of<p><pre><code> public interface ExampleInterface { void foo() throws IOException, AnotherException; } </code></pre> was not covered: is this also not supported?<p>That would solve a lot of use cases if inheritance is respected.
评论 #36736186 未加载
评论 #36736178 未加载
评论 #36736157 未加载
pshirshovalmost 2 years ago
The sad truth is: it&#x27;s pointless to talk about that with those who are not used to structures like Either&#x2F;Result&#x2F;IO monads. And those who are already know why and don&#x27;t need such articles.
EricRiesealmost 2 years ago
Java has a lot of &quot;throwingness polymorphism&quot;. You can extend an interface to say a method throws a subclass of the Exception thrown by the parent interface method. You can extend an interface and say that that method actually doesn&#x27;t throw an exception at all.<p><pre><code> interface NonThrowingAutoCloseable extends AutoCloseable { void close(); } </code></pre> You can also declare that you throw a generic exception type<p><pre><code> interface ThrowingSupplier&lt;E extends Exception&gt; { void get() throws E; }</code></pre>
jacquesmalmost 2 years ago
Erlang does this the right way: the process fails (the Erlang sub-process) but the super visor tree anticipates such failures and will restart the process that failed which if the rest of the application is properly designed will handle the error without loss of consistency. Depending on the failure it can also escalate further up to deal with larger and larger levels of malfunctions. Properly implemented short of gross hardware failure (all nodes down) this will result in a system that is always at or near the maximum possible availability as permitted by the hardware.
adamwkalmost 2 years ago
I think Swift’s error model is my favorite (though Go’s new error stuff seems similar). Unrecoverable errors are unrecoverable (they’re aborts) and other errors are marked in the function’s signature and must be handled explicitly. This means the error effect is explicit along the call stack until somebody handles it
smrtinsertalmost 2 years ago
They didn&#x27;t fail. I find them useful and great in code reviews where I can see juniors trying to get away with bad practices because they don&#x27;t feel like making the possible issues known to business owners.
aibalmost 2 years ago
I think the reason is simpler: Unchecked exceptions.<p>Investing in (checked) exception safety is not as valuable when anything can throw an NPE.
hota_mazialmost 2 years ago
Checked exceptions failed because developers are lazy and don&#x27;t want to check for errors.<p>Checked exceptions force you to do more work, but it&#x27;s essential work to make your code more robust.<p>Replacing them with runtime exceptions gives you the illusion of clearer code, but all you have is actually code that is more likely to crash.
评论 #36740718 未加载
he0001almost 2 years ago
Checked exceptions are great. But they were abandoned due to the functional paradigm so now it’s cumbersome to use them. Errors should be first class of any language and not bolted on as some sort of afterthought, language or design. Errors are something that occurs in real life and should be handled as such. Unchecked errors are a pain to deal with and always are unexpected which you need to dig into the code to see if they are thrown. This is a huge issue for me. I believe that Java should and could make them more easier to use by adding language support to transform them.
评论 #36736475 未加载