How to handle errors loading with the Flex Sound class - apache-flex

I am seeing strange behaviour with the flash.media.Sound class in Flex 3.
var sound:Sound = new Sound();
try{
sound.load(new URLRequest("directory/file.mp3"))
} catch(e:IOError){
...
}
However this isn't helping. I'm getting a stream error, and it actually sees to be in the Sound constructor.
Error #2044: Unhandled IOErrorEvent:.
text=Error #2032: Stream Error. at... ]
I saw one example in the Flex docs where they add an event listener for IOErrorEvent, SURELY I don't have to do this, and can simply use try-catch? Can I set a null event listener?

IOError = target file cannot be found (or for some other reason cannot be read). Check your file's path.
Edit: I just realized this may not be your problem, you're just trying to catch the IO error? If so, you can do this:
var sound:Sound = new Sound();
sound.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
sound.load(new URLRequest("directory/file.mp3"));
function ioErrorHandler(event:IOErrorEvent):void {
trace("IO error occurred");
}

You will need to add a listener since the URLRequest is not instantaneous. It will be very fast if you're loading from disk, but you will still need the Event-listener.
There's a good example of how to set this up (Complete with IOErrorEvent handling) in the livedocs.

try...catch only applies for errors that are thrown when that function is called. Any kind of method that involves loading stuff from the network, disk, etc will be asynchronous, that is it doesn't execute right when you call it, but instead it happens sometime shortly after you call it. In that case you DO need the addEventListener in order to catch any errors or events or to know when it's finished loading.

Related

is it necessary to revert something when using return inside a changeCompany

I have to add a control inside a changeCompany() in an existing class.
I suppose the code below is OK, but I have a doubt : Does the "return" order imply that a return to the original company is done ?
Or is there to add a statement, unknown by me, something like revertToPreviousCompany()?
try
{
changeCompany(companyId)
{
// the method will produce a message and return false if an error
if (!this.doSomeChecks()) {
return;
}
// much more code below
Yes that is OK as in some situations you wouldn't even be able to revert it if not done by the runtime itself.
Imagine a callstack in which you have try - catch around some code your are calling and you expect there may be thrown an error but if the code which calls your code already established a transaction your handler is not called and therefore you wouldn't have a chance to undo the changeCompany

Flex: recover from a corrupt local SharedObject

My Flex app uses local SharedObjects. There have been incidents of the Flash cookie getting corrupt, for example, due to a plugin crash. In this case SharedObjects.getLocal will throw an exception (#2006).
My client wants the app to recover gracefully: if the cookie is corrupt, I should replace it with an empty one.
The problem is, if SharedObject.getLocal doesn't return an instance of SharedObject, I've nothing to call clear() on.
How can I delete or replace such a cookie?
Many thanks!
EDIT:
There isn't much code to show - I access the local cookie, and I can easily catch the exception. But how can I create a fresh shared object at the same location once I caught the exception?
try {
localStorage = SharedObject.getLocal("heywoodsApp");
} catch (err:Error) {
// what do I do here?
}
The error is easily reproduced by damaging the binary content of a Flash cookie with an editor.
I'm not really sure why you'd be getting a range error - esp if you report that can find it. My only guess for something like this is there is a possibility of crossing boundries with respect to the cross-domain policy. Assuming IT has control over where the server is hosted, if the sub-domain ever changed or even access type (from standard to https) this can cause issues especially if the application is ongoing (having been through several releases). I would find it rather hard to believe that you are trying to retrieve a named SO that has already been named by another application - essentially a name collision. In this regard many of us still uses the reverse-dns style naming convention even on these things.
If you can catch the error it should be relatively trivial to recover from: - just declare the variable outside the scope of the try so it's accessible to catch as well. [edit]: Since it's a static method, you may need to create a postfix to essentially start over with a new identifier.
var mySO:SharedObject;
....
catch(e:Error)
{
mySO = SharedObject.getLocal('my.reversedns.so_name_temp_name');
//might want to dispatch an error event or rethrow a specific exception
//to alert the user their "preferences" were reset.
}
You need to be testing for the length of SharedObject and recreate if it's 0. Also, always use flush to write to the object. Here's a function we use to count the number of times our software is launched:
private function usageNumber():void {
usage = SharedObject.getLocal("usage");
if (usage.size > 0) {
var usageStr:String = usage.data.usage;
var usageNum:Number = parseInt(usageStr);
usageNum = usageNum + 1;
usageStr = usageNum.toString();
usage.data.usage = usageStr;
usage.flush();
countService.send();
} else {
usage.data.usage = "1";
usage.flush();
countService.send();
}
}
It's important to note that if the object isn't available it will automatically be recreated. That's the confusing part about SharedObjects.
All we're doing is declaring the variable globally:
public var usage:SharedObject;
And then calling it in the init() function:
usage = SharedObject.getLocal("usage");
If it's not present, then it gets created.

Flex Error #1009: Cannot access a property or method of a null object reference

I'm getting error while running a game I created with flex.
I know there has been some question about this, but my case is quite weird. I created a simple typing game that is running OK on my computer, but when I tried to deploy it online to facebook, I got those errors. I used code from the tutorial from adobe here http://www.adobe.com/devnet/facebook/articles/flex_fbgraph_pt4.html to deploy my flex game to facebook
This is the error message:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at FacebookUserStatusWeb/init()
at FacebookUserStatusWeb/___FacebookUserStatusWeb_Application1_creationComplete()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()
at mx.core::UIComponent/set initialized()
at mx.managers::LayoutManager/doPhasedInstantiation()
at mx.managers::LayoutManager/doPhasedInstantiationCallback()
And here is snippet of the init() function:
protected var text1:String="Text to be typed"; //hard-coded temporarily
protected const TIMER_INTERVAL:int = 10;
protected var t:Timer = new Timer(TIMER_INTERVAL);
protected var topURL:String=ExternalInterface.call('top.location.toString');
protected function init():void
{
t.addEventListener(TimerEvent.TIMER, updateTimer);
ProblemText.text = new String(text1);
Facebook.init("<my app id>",loginHandler);
currentState = (topURL) ? "loggedout": "loggedoutonfacebook";
}
Some notes:
1.my app id is my facebook app id which I prefer not to show
2.ProblemText is a richtext which I placed the paragraph to be typed by the player.
3.I have deleted the method Application1_creationComplete() but it still appears at the error listing
And also I am curious about the errors other than the first two. What do they mean?
Ah, and if it is helpful, I can post some more of the code
First: You're only seeing one error. Everything you see below the #1009 error is your stack trace, not additional errors.
The stack trace basically tells you the series of things that happened prior to the error occurring, with the most recent at the top. This is useful because often things which happen prior to the actual error you see will contribute to said error.
Second: The null object reference is occurring because something in your init() function tried to access a property in an object that doesn't exist, or an object that doesn't exist. One (slightly messy but effective) way to debug this would be to drop some trace statements in the code to see how far it gets before barfing with the error -- the idea being to isolate the specific line that's causing the problem. Once you've done that, you need to work backwards to figure out why the object or property you're trying to use is null. It could be something simple, like a typo, or it could be more complex. You'll have to sleuth it out, one way or another =)
Good luck!
Finally got the bug. Just in case people have the same case with me, what exactly happened is at my computer I simulated the game with just one state, but when I'm deploying to facebook I have several states (loggedin,loggedout,etc). In the init() I tried to access ProblemText Label that is not present in the current state.

Response.Redirect exception

Executing the line:
Response.Redirect("Whateva.aspx", true);
Results in:
A first chance exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll
An exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll but was not handled in user code
The exception is because of the "true" part, telling it to end the current request immediately.
Is this how it should be?
If we consider:
Exceptions are generally considered heavy, and many times the reason for ending the request early is to avoid processing the rest of the page.
Exceptions show up in performance monitoring, so monitoring the solution will show a false number of exceptions.
Is there an alternative way to achieve the same?
You're right regarding the fact that the developer should avoid raising of (and catching) exceptions since the execution runtime consumes time and memory in order to gather the information about the particular exception. Instead he (or she) should simply not let them occur (when it's possible).
Regarding the Response.Redirect: this behavior is "by-design" but you might want to use a well-known workaround. Please read this KB article.
-- Pavel
One approach I generally take in this scenario is to not end the response during the response, but to follow it immediately with a return (or other flow control). Something like this:
Response.Redirect("Whateva.aspx", false);
return;
This depends on where the redirect is taking place in your logic flow, of course. However you want to handle it is fine. But the idea is that, when you want to end the response on the redirect anyway, then exiting the method in question via a return isn't out of the question.
One approach I've seen people take in this matter quite often, and it should go without saying that this is to be avoided but for completeness I'm going to say it anyway (you never know who may stumble upon this question later via Google, etc.), is to catch and swallow the exception:
try
{
Response.Redirect("Whateva.aspx", true);
}
catch (Exception ex)
{
// do nothing
}
This, of course, should not be done, for a number of reasons. As I inferred from your description of exceptions, you undoubtedly already know that this would be bad practice. But, as I said, it's worth noting this fact in the answer.
To work around this problem, use one of the following methods:
For Response.End, call the HttpContext.Current.ApplicationInstance.CompleteRequest method instead of Response.End to bypass the code execution to the Application_EndRequest event.
For Response.Redirect, use an overload, Response.Redirect(String url, bool endResponse) that passes false for the endResponse parameter to suppress the internal call to Response.End.
For example:
Response.Redirect ("nextpage.aspx", false);
If you use this workaround, the code that follows Response.Redirect is executed.
For Server.Transfer, use the Server.Execute method instead.
from:
http://support.microsoft.com/kb/312629/en-us
Same link posted by Volpav.
Regards.

HTTPService not retrieving current data

I'm using mx.rpc.http.HTTPService to retrieve data from a web service. On the initial call to "loadWsData", HTTPservice accurately retrieves all the data.
However, on any and all subsequent calls HTTPService does not accurately retrieve the data; rather it always retrieves the first data set. I've confirmed that the web service is providing accurate data, both from web browsers and a ruby ws client script.
My code is below; any ideas on what could be the problem?
private function loadWsData(id:int):void
{
var webService:HTTPService = new HTTPService();
webService.url = "http://xxx.xxx.xxx.xxx:8080/profile/ + id;
webService.method = "GET";
webService.addEventListener(ResultEvent.RESULT, function(event:ResultEvent):void
{
var rawData:String = String(event.result);
var user:Object = JSON.decode(rawData).user; // User object always reflects the first data set retrieved.
....
....
});
webService.send();
}
Not sure what the issue might be, but I have a few suggestions on where to look.
First, there appears to be a bug in your code; the webService.url line is missing a quote mark. That could be messing up the URL you think you are sending. Odd, though, because I don't think what you have shown would compile, so I suspect this is just a cut-and-paste error when you posted this to StackOverflow, but I would trace out that URL just to be sure.
Also, I don't see code to remove the event listener (although it could be in the code you have abbreviated with ellipsis). Is it possible that there are lingering event listeners that are firing in addition to the ones you expect? If the original event listener fires, it will fire with the original data.
Another suggestion: instead of using a closure, try pulling it out to a separate function. That shouldn't be the issue, but maybe scope is playing a role here.
You could try to POST your results.
You might also add an event listener for FAULT, and see if there are any errors being thrown by your service request.

Resources