Why isn't my exception being caught? - actionscript-3

This is the stack trace I get:
[Fault] exception, information=Error: Directory id 3 already in use
at cantrips.assets.index::AssetIndex/dirIdChanged()[/home/luismasuelli/Proyectos/flash-assets-index-ritual/assets-index-loader/src/cantrips/assets/index/AssetIndex.as:72]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at cantrips.assets.index::AssetDirectory/set id()[/home/luismasuelli/Proyectos/flash-assets-index-ritual/assets-index-loader/src/cantrips/assets/index/AssetDirectory.as:68]
at Main/updateSelectedDirectory()[/home/luismasuelli/Proyectos/flash-assets-index-ritual/assets-index-editor/src/Main.mxml:192]
at Main/__dirUpdateCurrent_click()[/home/luismasuelli/Proyectos/flash-assets-index-ritual/assets-index-editor/src/Main.mxml:401]
This is the implementation of Main/updateSelectedDirectory():
private function updateSelectedDirectory():void {
try {
var newId:uint = uint(dirId.text);
var newName:String = StringUtil.trim(dirName.text);
var selectedDirectory:AssetDirectory = assetBrowserTree.selectedItem as AssetDirectory;
if (selectedDirectory) {
selectedDirectory.id = newId;
selectedDirectory.name = newName;
assetBrowserTree.expandItem(selectedDirectory.parent, false);
assetBrowserTree.expandItem(selectedDirectory.parent, true);
}
} catch (error:Error) {
Alert.show(error.message, "Cannot update");
}
}
Why is not the exception being caught by try {} catch(error:Error) {}?.
The exception is an exception created by me, with a well-understood scenario where it is triggered (I created the exception and designed those scenarios and I am testing them; exception is triggered as I expect). I also tried using the exact name of the exception (AssetIndexError) in the catch block, and no confusion or ambiguous name exists (this means: there's no another AssetIndexError class declared elsewhere I could be importing instead of this).
Explanation:
cantrips.assets.index is code I have control over.
Main/* is the main window. I also have control over that code.
Screenshot:

If you look at your stack, you'll see the error is not being thrown in the code shown (which is near the bottom of the stack), but here:
dirIdChanged at AssetIndex.as:72
Further down in the stack you'll see the following:
at flash.events::EventDispatcher/dispatchEvent()
This means that stack was asynchronous in between AssetDirectory.set id() and
AssetIndex.dirIdChanged()
When you add an event handler, all code in the current block will usually run prior to the event handler code (as they are not in the same thread).
So in this case, all your code in the try/catch will have run before the event handler's code - which is why the error is not being caught.
Any time you are handling an event, you will need to have another try/catch, or use an asynchronous error handling technique.

This is a complement the OP made to the accepted answer.
The main reason of this trouble is that I did not understand how the event flow is done.
The event flow is asynchronous, and I thought as it being synchronous. If the event flow was synchronous, it is not hard to think that what I intended was right: The exception could be thrown in the same execution stack and everything would be fine (i.e. a method calls another method, such method calls a third method, blah blah blah exception and explosion).
When the event flow is asynchronous as ActionScript flow is, the exception will be triggered in another execution stack, but somehow the information provided is misleading as it should as if the execution stack was the same.
The solution I implemented: A dumb object (i.e. a dumb new class) which acted like EventDispatcher but being synchronous: .dispatch() would not post an event execution to the event flow, but instead execute by itself the registered event handlers, as a loop over the handlers, and calling each handler by hand, without the possibility of having stuff like event.target populated in the handlers.
Althought this design could be seen as bad from many points of view I would agree with, in this case it fit my needs of handlers throwing exceptions and code executed synchronously.

Related

Exceptions in Lablgtk callbacks

In Lablgtk, whenever there is an exception in a callback, the exception is automatically caught and an error message is printed in the console, such as:
(prog:12345) LablGTK-CRITICAL **: gtk_tree_model_foreach_func:
callback raised an exception
This gives no stack trace and no details about the exception, and because it is caught I cannot retrieve this information myself.
Can I enable more detailed logging information for this case? Or prevent the exception from being caught automatically?
I guess the best way to do so is to catch your exception manually and handle it yourself.
let callback_print_exn f () =
try f () with
e -> my_exn_printer e
Assuming val my_exn_printer : exn -> unit is your custom exception printer, you can simply print your callbacks exceptions by replacing ~callback:f by ~callback:(callback_print_exn f) in your code.
Of course, you can also with that method send that exception to another
thread, register a "callback id" that would be passed along with your exception...
About the stack trace, I'm not sure you can retrieve it easily. As it's launched as a callback, you probably want to know the signal used and that can be stored in your callback handler.
I had another similar issue, but this time it was harder to find where to put the calls to intercept the exception.
Fortunately, this time there was a very specific error message coming from the Glib C code:
GLib-CRITICAL **: Source ID ... was not found when attempting to remove it`
Stack Overflow + grep led me to the actual C function, but I could not find which of the several Lablgtk functions bound to this code was the culprit.
So I downloaded the Glib source, added an explicit segmentation fault to the code, compiled it and used LD_LIBRARY_PATH to force my modified Glib version to be loaded.
Then I ran the OCaml binary with gdb, and I got my stack trace, with the precise line number where the Lablgtk function was being called. And from there it was a quick 3-line patch.
Hacks like this one (which was still faster than trying to find where to intercept the call) could be avoided by having a "strict mode" preventing exceptions from being automatically caught. I still believe such a switch should be available for Lablgtk users, and hope it will eventually be available.

async void, await, and exceptions - why do exceptions thrown after 'await' from the GUI thread require AsyncVoidMethodBuilder for marshaling?

In C# 5.0 In A Nutshell, pg 590, the following example is given:
async void ButtonClick (object sender, RoutedEventArgs args)
{
await Task.Delay(1000);
throw new Exception ("Will this be ignored?");
}
The book states that the Exception will not be caught because the function will imediately return to the message loop at the await line, and when the exception is thrown one second later it will not be caught by the try/catch in the message loop.
The book goes on to state that AsyncVoidMethodBuilder has to encapsulate the continuation within another function so that it can build another try/catch block and forward any caught exceptions to the synchronization context if it is present.
This confuses me because I thought that, since the Task.Delay was being called from the GUI thread, the presence of the syncronization context would cause the continuation from Task.Delay to execute on the GUI thread already. I would have thought that it could therefore continue exeuction directly from the message loop inside a try/catch clause and still get caught without needing to be encapsulated in another function.
What am I missing?
Your understanding is correct; the exception will be re-raised directly on the UI SynchronizationContext and be caught by the message loop. From there it will pass to the UI application-wide handler.
What the book actually says is that the exception cannot be caught after the async method returns, and this is why the AsyncVoidMethodBuilder will re-raise the exception on the appropriate SynchronizationContext.
This is important because an async void method may "leave" its UI context, e.g., by using ConfigureAwait(false). But if an exception happens after that point, it must re-sync to the original SynchronizationContext, not necessarily the context at the point the exception is thrown.

Breeze EF6 SaveChanges doesn't propagate exceptions

In the EFContextProvider (EF6) SaveChangesCore method, the exception handling looks like this:
} catch (Exception e) {
while (e.InnerException != null) {
e = e.InnerException;
}
throw e;
}
This throws only the most internal exception and hides the relevant information revealed by the external exceptions.
When the SaveChanges process goes through multiple layers the next direct layer exception is lost, and only the last exception in the chain is thrown. It doesn't allow to handle well the exceptions for the caller.
Updated Post
As of Breeze 1.4.6, any .NET Exceptions thrown on the server are now available in their original form in the httpResponse.data property of any async breeze result. Breeze will still drill down to extract a "good" error message, but will no longer obscure the initial exception.
Original Post Below -------------------
It's an interesting point. The reason we did this was because most client side apps aren't written to navigate thru the exception chain and we wanted to expose the most 'relevant' error to the client. Most of the apps we looked at just exposed the client "error.message" property directly and with EF errors this was almost always useless.
However, your point is well taken. I think what we need to do is create a new Exception that has a top level message that is the innermost exception message but still expose the entire exception chain for those that want to drill. I've added an internal feature request for this and will try to get it into a near term release ( probably not the next one because we are already in testing for that one).
And thanks for the input.

What is the usefulness of using throw? and in catch?

From what I understand throw causes an exception.
It looks like it can be used to test your catch exception.
What are the benefits/uses for it? Why would you want to purposely cause an exception?
Why use throw in catch? Seems like it catches the exception just to cause an exception again.
try
{
//blah
}
catch
{
throw;
}
throw; rethrows the current exception. It's used for when you want to catch an exception and do some handling of your own, but otherwise still want the exception to propagate more-or-less as if you never caught it.
The difference (in languages that let you just say throw;, like C#) is that when you rethrow an exception, the original stack trace remains mostly intact. (It includes the line where you rethrew the exception rather than the line where the exception occurred in the corresponding try block, but otherwise the whole stack trace is preserved.) If you say throw the_exception_you_caught;, it's usually treated as if you threw a brand new exception from right there -- the existing stack trace gets obliterated and a new one starts from that point.
Exceptions are mechanism for error handling. For instance, you may throw an exception to indicate that a webservice call has timed out, or bad input as been provided to a method. The idea is that calling code knows how to deal with these exceptions and handles them gracefully — perhaps fixing what's wrong in the case of bad input (by prompting the user) or by trying a callout a second time.
A catch block is where you do your handling of the error, and in certain scenarios you may want to do some local cleanup in the method running, but then you still need to report the error to calling methods, so you throw the exception once more (or throw a different, maybe more generic or specific exception) which you then handle in your calling code.
Description
You can do this to, for example, log something and give the exception back to the calling method / assembly.
You can handle the exception and signals the caller that a exception is happend instead of return a boolean that indicates if the method has success.
This is useful for unit tests and more.
Sample
try
{
//blah
}
catch
{
// log exception to textfile of database
throw;
}
This is a common pattern in .Net code. It's used when the caller wants to either log, wrap or react to an exception and then pass it back up to the caller. For example
try {
SomeFunction();
} catch {
CloseMyResource();
throw;
}
The advantage of throw vs throw exceptionVariable is that throw preserves the original stack trace. The next person to catch the exception sees the original stack trace. This is essentially for tracking down errors in deep call stacks.
I think it may be better to think of a throw as your informed reaction to an exception in your code rather than the cause. Semantics I know but it helps.
You throw a different exception in a catch to add information. Your converting what may be a generic OS exception into one meaningful to your application. e.g. Out of memory exception may be caught and a new exception with the out of memory as the inner exception be throw saying something like "Error while computing the answer to life the universe and everything". More useful that just an out of memory exception.
You may use a 'throw' on its own as a rethrow. The catch allows you to do something before rethrowing. If we are talking C# check out 'finally'.
When something really bad happens, that ought not happen, then you can abort and inform the caller by throwing an exception. It means that you do not need to have every method returning result codes and every caller testing fault/success codes. It also nicely abstracts who handles such 'exceptions' or even if you just leave it to the OS.
Quick answer ... it makes your code simpler and gives you better control of aborting and handling exceptions. Think of it as a messaging/abort system.
You would re-throw the same exception if you wanted to do some logging here or some clean up but would like to still have the calling functions further up the call stack to have to handle that same exception.
A more typical use would be:
try {
// ...
} catch (EmailException ex) {
SMS.AlertError("Email is not working", ex);
throw;
}
If you throw ex you will have stripped out information such as the call stack from the exception.
The some function above that would:
try {
// ...
} catch (Exception ex) {
WorkFlowProblems.Add(new OrderNotSentException("Email did not work", ex));
View.ShowError("Could not send order!");
}
Here you make a new exception and set it's "inner exception" to be original cause. This is a good way for multi-part systems to have the right level of information about what went wrong and at what level.
Doing this preserves the stack trace. In your example, it's not useful, however, you could catch the exception, log it and then rethrow so that the exception bubbles up to be handled by code higher up.
The place where throwing exception (in my opinion) is MOST useful is when you want to create an instance of a new object and there's some possibility that the instance needs to fail in creation, in which case the instance can be made to remain null (since constructors don't "return" anything... so for example...
Foo foo = new Foo();//
//at this line foo may or may not be the exact thing you want it to be, depending on whatever conditions made the creation of Foo possible.
So, Foo throws an exception you can do this:
Foo foo = null;
try{
foo = new Foo();
}catch(FooException fe){
//here you can find out if Foo didn't get instantiated as you wanted it to
}
//and here you can test if foo is still null.

Handling Security Errors in AS3

I am using an imported class for a vimeo player in AS3, it is the official vimeo player api (vimeo.com). I want to handle any Security Errors that an instance of the class throws (they get thrown when the obect fails to load an external URL for a video). This is what I have got:
var clipPlayer = new VimeoPlayer("5d22d3942a54d7c75b931bab4a911857", videoID[clickedClip], fullVideoWidth, fullVideoHeight, "10", 2);
clipPlayer.addEventListener(SecurityErrorEvent.SECURITY_ERROR , vimeoError);
Later in the code ofcourse, I've got the function that handles the event:
function vimeoError (e : SecurityErrorEvent) : void {
trace("vimeo player failed to load");
}
This all seems straight forward, but yet the Error Handler is not firing. I must be missing something here... Maybe you can't register this kind of event listener on a VimeoPlayer object. However, I am pretty certain it is the VimeoPlayer object throwing them. Here is an example of what I am getting:
Error opening URL
'http://api.vimeo.com/moogaloop_api.swf?oauth_key=5d22d3942a54d7c75b931bab4a911857&clip_id=21185860&width=500&height=281&fullscreen=0&fp_version=10&api=1&cache_buster=565.7249609939754'
SecurityError: Error #2000: No active security context.
Dispatched error events are separate from thrown Errors. In many cases both kinds can occur, and then you need to listen for the former and catch the latter with a try statement around the code that may throw. The error you quote seems to be of the thrown variety (as events typically stringize to something involving square brackets).