- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Such a handy feature! I would suggest to implement Exception as a K61Exception, to extend functionality to all Exceptions! }
Admin
I confess, I see this as an example of bad naming. I'd probably have called it, "unrecoverable" or "isUnrecoverable" - a way of saying, "This exception you cannot recover from".
Sadly, when doing DCOM or integrating to older languages, the only way to handle something has gone wrong is by a non-0 / exceptional result. You then have to pick through the exception type to determine - is this really something we need to blow up on, or is it a business-as-usual error (the user you passed in is unauthorised to perform this action, the user doesn't have enough funds, the user entered a duff URI for us to scrape... the list goes on).
Admin
I have a feeling that they are misusing Exceptions as control flow (like for breaking out of a loop) and therefore need this flag.
Admin
Heh, this reminds me of some code one of my students once wrote. Call it "Exception is the rule" or "Function of no return" if you like. Recreating it from memory, so I'll stick to Java-like pesudocode.
Problem - deep labyrinth of recursion and iteration digging around a large data structure in memory. How do you get out of this quickly once you've found/computed what you were looking for? Like this :
// ... skipping the rest of class definition void doStuff(/some arguments/) throws SuccessException, NoDataException, SomeMoreExceptions { // do some stuff to prepare the job try { startWorking(/*some args */); } catch (Exception e) { throw e; } throw new NoDataException(); }
Yes, really. Some exceptions might get legitimately thrown, that's an actual exception, so pass them out - this one's fine. Then we might not have been able to find the solution, in which case we throw a custom NoDataException - that's sort of ok, it's rare and there's no usable output, so yeah, it is an exception. And then you have the custom SuccessException, which actually stores the result(!) - it gets thrown once it's ready, collapses the call stack, and gets to our main function. That's not the right way to use exceptions, but it would be just an internal WTF if we unwrap the result and return it like a civilized method. But nooo, we don't do that stuff here! We just pass it out, leaving the task of extracting the result from the SuccessException.
You read that right. This method never returns normally. It always throws something. Very rarely a normal exception, sometimes a custom but acceptable exception meaning "no result", usually the great beautiful SuccessException.
The class name of that exception (yes, it actually WAS called SuccessException) has entered my dictionary as a synonym of WTF.
Bonus points if you guessed that SuccessException actually extends Exception. I would have been a bit less irritated if it at least extended Throwable instead and was called something like ThrowableResult...
Admin
I wonder how far you could go with that. Like, imagine a program structured around one giant dispatcher function that is entirely composed of exception handlers and a switch. And the rest of the program communicates with this function by throwing exceptions in order to invoke function calls like some sort of demented deformed event handler. Not that the idea would be good if it were done with event handlers. But cool none the less.
Admin
Gah, sorry for the unreadable code, forgot to mark it... I hope it still makes sense.
Admin
As code design goes, a little feeble. At the very least implement an enum, with values Bad, VeryBad, PrettyDamnBad, ReallyReallyBad, Nightmare, OhBugger.
I did once have to maintain an application which had numerous error cases, all of which could be triggered by bad data, all of which passed control to an error branch, which printed out "oh bugger" and exited.
Admin
It more a fundamental misunderstanding of classes. Rather than an isUnrecoverable method, extends UnrecoverableException is "more OO". It's also more suited to how exceptions are caught; catch (UnrecoverableException) is much more readable than having a switch or if in a generic exception handler.
Admin
In general a really UnrecoverableException is would be an Error, a different Throwable, wouldn't it?
Admin
While I appreciate the approach, it's still a half-hearted effort. What is needed is the active complement, a method
isNotAnException()
, which makes the Exception go away. Every programmer should be provided with the means to answer back to realities that might be messing with their beautiful code!Admin
I get the feeling the developer who named this flag may have been working under duress. They were forced, either by management or by existing designs, to use exceptions in unexceptional circumstances (or maybe this exception class was already in use before they added the flag, and they couldn't change that usage). They complied, but they managed to protest in some small way through the naming of the flag.
If they had actually wanted to design the exception this way, they would have named the flag something like
isError
,isException',
exceptionType, or
b. The name
isReallyAnException` seems to say, "I acknowledge the stupidity of this flag, but here it is anyway."Admin
Is this really a comment?
Admin
Though actually, what would you suggest? Let's take an extreme case, like various places of recursive calls, perhaps even indirectly though several functions, vs. one place where a result is found.
The typical approach of returning the result level by level is just as cumbersome as non-exception-based error handling and may hurt performance. (Since recursion tends to exhibit exponential growth, performance may matter.)
So with better inheritance and naming (such as "ThrowableResult"), and internal catching and unwrapping, is this so bad?
Admin
Ceci n'est pas un Exception.
Admin
I think the answer here is "It depends on the language".
For example, Java, which this submission appears to be and the student's code almost certainly was (based on Throwable), has really heavy Exceptions/Throwables due to generating full stack traces on creation. (It is possible to prevent this by overriding
fillInStackTrace()
, but neither code likely did this; it's very obscure.)Python, on the other hand, uses exceptions for flow control as part of the language. (You exit a
for
loop by having the iterator raiseStopIteration
, for example). Exceptions are much lighter and more "expected" in Python, so it's natural there.Admin
Error
is reserved (or used to be reserved) for internal issues in the JVM. I would subclassRuntimeException
which is also unchecked.Admin
There are various languages that abuse exceptions, and this is a workaround. You get loads of 'exceptions' that are expected and need to be filtered out of the logging.
Admin
Returning and propagating that result up the call stack is the right way to do it. Even with no optimisations it's likely to be more performant - exceptions are really expensive. If your recursive method can be optimised as tail recursion then returning up the stack will optimise away into a single return anyway.
Admin
You're right about tail recursion, so let's assume no tail recursion possible for the hypothetical example. :)
Exceptions may be expensive, but only by a constant factor. That's why I mentioned exponential growth (imagine a huge complex search and a single point of returning the result). A small overhead on each recursive call will easily outweigh any constant cost. Actually, the cost of returning the result by exception will probably be dwarfed by the cost of outputting (or otherwise using) the result.
Admin
I've been dabbling in Intellij plugin work and it has a couple different control flow "exceptions". It even complains at you in the log if you log them yourself. I guess it is one way to semi force most plugin code to respect a cancel. Unless of course you try to catch all exceptions in your plugin so it doesn't cause really strange ide behavior and forget to pass the control flow exceptions on which itself will probably cause more strange behaviour (like not canceling a heavy operation when the ide or user asks for it).
Admin
I had the same feeling, like maybe they inherited this from someone versed in a language like Python where you inevitably end up dealing with lots of exceptions thrown by mundane operations that should be expected to occasionally fail as part of normal program flow, and are thus not really exceptional. So there end up being lots of catch blocks that need to decide if what went wrong needs to be handled as a true exception versus a BS fake exception that's really a mundane thing that you would have been able to guard against using a less severe mechanism given a more reasonable language/API/library.
Admin
Count me amongst those who think this is really sorting out the this-can't-be-done "exceptions" from the something-unexpected-happened situations for which you probably should terminate.
The UnrecoverableException approach has been suggested and in most cases would be the best answer (but maybe not possible in legacy situations) but not all exceptions can be cleanly divided like that.
/0 error? If your code throws a /0 you no doubt have odoriferous fertilizer in the air mover. But what if it's not your code? Plenty of systems support some form of user language and if that language supports division you could have a /0 error that simply means you scold the script-writer, you don't need to terminate the program.
Admin
I despise "non-exceptional" exceptions.... IF you can test for it, then you should test for it. Consider an input file that is needed.... Don't throw an exception if it dowes not exist.... CHECK and handle with flow control. Then if the open fails throw exception (it is exceptional that the file was deleted in the uS between the two events)
Admin
" If your code throws a /0 you no doubt have odoriferous fertilizer in the air mover." ... but does that make it "unrecoverable" to the point were termination of the program is needed? I would say that would be a minority of the cases.
Admin
I guess those are expections then...
Admin
Admin
I don't know Java well enough, but would a call to isReallyAnException() just end up endlessly recursing the function, until the system generates a StackOverflow exception? So checking why K61Exception was thrown, would end up throwing a StackOverflow anyway?
Admin
It wouldn't.
isReallyAnException()
is a method call;isReallyAnException
, without the parentheses, is just a member variable. It's just like this:...except that the method and the variable happen to have the same names (which is fine, although it'd be more conventional to name the variable
reallyAnException
). Does that make sense?Admin
I'm reminded of a rash of success errors we had a while back.
Our team does a lot of work with a database API that usually returns a result code of 0 for success. The only exception happens with an operation that we never use., as it's used to handle a niche case that our DBAs chose to not present us. We could still use it, but it's a pain, and easier to not.
The API we use also provides us with an isError method, which helpfully determines whether the response was an error, regardless of what operation was performed. It's simple to use, and if one is not attempting to make ones script as blazingly fast as possible, it's kind of a no-brainer to use it. I mean, it's readable code, after all, so it's better than saying something like
if (result.code()) { // do error handling here }
But we had a bright bulb who thought he could get away with even fewer cycles than that.
if (result.count()) { // do error handling here }
But the thing is, returning no results is not an error when there's no matches. Also, their code was slower than
if (int error_code = result.code()) { // do error handling here }
Of course, there's also the thing that fast but wrong is not better than a microsecond slower but correct.
Eventually, he retired in 2012, and his code was all purged of that particular issue. But of course there's still others, as I found earlier today.
Admin
I'm firmly on the other side, but then again, I use python. Opening an existing file is a perfect example of when using the exception leads to more succinct and / or more correct code. You don't care whether the file existed 5 microseconds ago, that's irrelevant to the program.To be correct, you have to handle the case where the file disappears before you can open it, anyway. (On NFS, the check will also lead to additional, unnecessary protocol operations)
Maybe StopIteration (as menitoned by Anonymous) is pushing it a bit, but otherwise it's very useful and expressive to treat any small hiccups like that as exceptions. It would be great for atomic operations in multi-threaded programs, but Python isn't good with multi-threading.
Admin
Unless it's called from generated code, it's a WTF.
I used to maintain a compiler that used an "uncaughtable" exception to implement continuations. Scala does some trickery with exceptions when you need to generate code for a non-local return statement.
In such cases, you might see something like this.
Admin
I agree too - as the file-open operation will effectively check the file exists at the time it is used, and throw a suitably-named exception if it does not, writing an additional check before trying to open the file would be of little value.
It's just added complexity and since it does not cover all eventualities, the file-not-found exception may still be thrown and need to be handled - probably in the same way as the 'file not found status code' would need to be.
Admin
This seems to be inspired by ODP.NET and the "error" message that reads: "Package state has been reloaded."