Understanding exception handling mechanism (control flow) in Dart - dart

Assume we have this Dart code:
void main() {
try {
try {
throw null;
} catch(e) {
throw null;
} finally {
print('first');
}
} finally {
print('second');
}
}
When running this code in browser via http://try.dartlang.org
Produced result very expected.
first
second
Uncaught Throw of null.
But if running this code in Dart VM then result very unexpected.
second
Unhandled exception: Throw of null.
This looks like first termination block (finally) never be executed.
I cannot understand this behavior of the exception handling mechanism.
Of course, we can assume that this is a bug.
But exception handling is the cornerstone of any system.
How Dart developers can explain this disparity?
P.S.
I think this question related to theme "about programming" and asking it here are the right place and time?

This appears to be an error in the VM, as far as I can tell. I've filed a bug:
https://code.google.com/p/dart/issues/detail?id=11758&thanks=11758&ts=1373396821
I should add that while the code is illustrative of the differing VM and dart2js implementations, it is a little error prone. If you feel that your catch block is going to throw, wrap the code inside the catch block within its own try-catch.
And, yes, I agree that this is a fine question to ask on StackOverflow. Thanks for posting this.

Related

throw Exception('oops!') vs throw 'oops!'

I notices some code that made me think the Exception function call was optional? E.g., do these two lines perform the same function?
throw Exception('oops!');
throw 'oops!'
No.
The former, throw Exception('oops!');, creates a new Exception object using the Exception constructor, then throws that object.
It can be caught by try { ... } on Exception catch (e) { ... }.
The latter, throw 'oops!'; throws the string object.
It can be caught by try { ... } on String catch (e) { ... }.
Generally, you shouldn't be doing either.
If someone made an error, something that would have been nice to catch at compile-time and reject the program, but which happens to not be that easy to detect, throw an Error (preferably some suitable subclass of Error).
Errors are not intended to be caught, but to make the program fail visibly. Some frameworks do catch errors and log them instead. They're typically able to restart the code which failed and carry on, without needing to understand why.
If your code hit some exceptional situation which the caller should be made aware of (and which prevents just continuing), throw a specific subclass of Exception, one which contains the information the caller needs to programmatically handle that situation. Document that the code throws this particular exception. It's really a different kind of return value more than it's an error report. Exceptions are intended to be caught and handled. Not handling an exception is, itself, an error (which is why it's OK for an uncaught exception to also make the program fail visibly).
If you're debugging, by all means throw "WAT!"; all you want. Just remove it before you release the code.

Difference between 'catch(e)' and 'on Exception catch(e)' in dart?

What is the difference between catch(e) and on Exception catch(e) in dart?
AVOID catches without on clauses.
Using catch clauses without on clauses makes your code prone to encountering unexpected errors that won't be thrown (and thus will go unnoticed).
BAD:
try {
somethingRisky()
} catch(e) {
doSomething(e);
}
GOOD:
try {
somethingRisky()
} on Exception catch(e) {
doSomething(e);
}
Link: avoid_catches_without_on_clauses
The } on Exception catch (e) { will catch all thrown objects implementing Exception.
The excludes most errors (which implement Error),
The } catch (e) { will catch all thrown objects, both exceptions and errors - and anything else that might get thrown. Most thrown objects implement either Exception or Error, but that's just a convention. Any non-null object can be thrown.
I'd actually recommend against on Exception as well. Exceptions are not errors, they are intended for functions as an alternative to returning a value, but exceptions are still just as much part of the function API, and you should only be catching the exceptions that you are actually planning to handle. Since Exception itself has no information, you should be catching the subtype that the function is documented as throwing so you can use the available information to handle the exceptional case.
If you are not going to handle it, you might as well treat the exception as an error.
Using only } catch (e) { to catch everything is reasonable in some situations, mainly in framework code which wraps other user code, and needs to make sure a user code error or unhandled exception doesn't take down the entire program.

Does Apple encourage you to throw only single error type in Swift 2.0?

Please correct me if I'm wrong, but from what I understand with Swift 2.0 Apple really encourage you against having many catch statements to handle different error types. Instead in most cases your do-catch block would have only one catch statement that catches everything.
I'm not saying that this is a good or bad idea. But I just don't see any other option. You can't be 100% sure about error type that you may or may not receive after a function call. This is because there is no way to specify a list of possible errors in a function definition after "throws" statement. So you would need to dig into the call stack of the function to find this out. And this could be a very deep stack... Will anyone actually do this every time just to get the idea what to catch?
To demonstrate what I mean:
func funcA() throws {
throw SomeError
}
func funcB() throws {
if something {
throw OtherError
}
try funcA()
}
func funcX() throws {
try funcB()
}
Now I if I want to call funcX - I don't really know that it can throw SomeError or OtherError by looking at funcX definition. In order to find this out I will need to go and review the entire call stack tree from funcX. While it doesn't look too complex in the extremely short example above. But in a real world source code this may become an issue.

Do not stop test execution on XCTAssertThrowsSpecific

Using XCTest, a test does the following:
XCTAssertThrowsSpecificNamed([does something that breaks], NSException, NSInvalidArgumentException);
I don't want the debugger to stop on the NSException that I know will occur but I want it to still stop on other exceptions that might occur.
Basically we don't have a choice. I still consider it an xCode bug because you already told xCode an exception will be thrown, and what exception it will be. Why provide XCTAssertThrows if it's an exception you're not "expecting"?
Obviously it's for exceptions you are expecting, which #nhgrif argues should be an error, not an exception. Might be a good point, but i do want my program to crash if this case ever happens, because I can't handle it.
So the real question is more why not disable the debugger on that exception only? Probably because they haven't gotten around to it. I'd suggest opening a bug/feature request with Apple. I'd love for someone to contradict me on this (please comment!) but until then, I'll live with this issue (disable debugger when running all my tests).
--> https://stackoverflow.com/a/22393643/1701430
"Why does the test stop when the execution is thrown?"
Because you have a breakpoint, which stops execution.
"Why, after removing the breakpoint, does my application crash when the exception is thrown?"
Because you have an unhandled exception. Unhandled exceptions cause your program to crash.
"How can I handle an exception so it won't crash my program?"
The easy answer to this question is to simply NOT throw an exception. In other programming languages, like Java, this is perfectly standard. But in Objective-C, we don't really do exceptions. In Objective-C, exceptions should be saved for TRULY exceptional behavior.
With that said, and a strong suggestion for you to find another way to handle whatever it is you're trying to handle, this is how you handle an exception in Objective-C:
#try {
// code that could throw an exception
}
#catch (NSException *e) {
// handle the exception...
}
#finally {
// post try-catch code, executed every time
}

BlackBerry - global exception handler

(edit: this question is about BB specifically, because of the strange way it optimises exceptions. I am comfortable with normal exception handling patterns in J2SE, but BB does not behave as per normal. Specifically in this case, BB discards the error type, and message, and how BB devs try to deal with this issue, or if they ignore it.)
I would like to implement some form of custom global error handling in my BB app. Specifically to try to handle any other exceptions that were not caught by my code, because I had not expected them. The default behaviour is that the app fails, and a dialog pops up saying an Unknown error occured.
I would like to describe the error a little bit better, hence my term "global error handler". Something similar to the code:
public static void main(String[] args)
{
try
{
FusionApp app = FusionApp.getInstance();
app.enterEventDispatcher();
}
catch (Throwable t)
{
// t has lost all type information at this point - this prints "null"
System.err.println(t.getMessage());
}
}
My immediate problem is that when I catch t (in the main() method after the app.enterEventDispatcher() call), it has lost its type information. e.g. I know that the code throws an IllegalArgumentException with a custom message - however in the catch block, it is a java.lang.Error with null message.
And in the stack trace (ALT LGLG), the message has also been lost (at least the stack trace is accurate).
So... what is a good pattern to use to implement some form of global error handling on BB? Or is this considered a bad idea on this platform?
Is it considered good practice to just have the unknown error dialog box pop up - I don't like this, but maybe that is the way of the BB?
Best practices are to implement custom exception handling.
So, if you expecting to catch IllegalArgumentException, MyCustomException and StartupException, put them into catch block first, and then put an Exception catch (and then, if you like, put a Throwable catch)
The common rule is - from most exclusive to most common, and for exceptions of the same level - from most expected to least expected.
In case of exception == null or getMessage() == null you can always display something like "Application error, please send event log to [support email]" message, then if you have a nice event logging in you app, you have a good chance to reproduce an issue.
And talking about event log, see EventLogger class to implement logging.

Resources