Should I call close() on URLLoader after an error? - actionscript-3

When using URLLoader two types of errors are possible: exceptions which can be catched in try {} block and error events which can be handled by handler functions.
Should I call close() on my URLLoader object after exception/error event occurs?

Interesting question - I gave this code a try and didn't get the error you would expect (stream error):
var urlLoader:URLLoader = new URLLoader();
urlLoader.load( new URLRequest("http://stackoverflow.com/test.jpg") );
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, error);
function error(e:IOErrorEvent):void
{
// Don't get the stream error, meaning the stream is still open.
urlLoader.close();
}
I then thought to myself that maybe it just closes half a second later, so I attached a setTimeout() to the close call. Still didn't get the error.
function error(e:IOErrorEvent):void
{
setTimeout(function()
{
// Still no error.
trace("Test.");
urlLoader.close();
}, 3000);
}
To double check, I ran this to make sure we still actually get that error:
var urlLoader:URLLoader = new URLLoader();
urlLoader.close(); // Error: Error #2029: This URLStream object does not have
// a stream opened.
So, it seems as though you actually do need to .close() a stream if there is an error. How weird. That said, I am still in disbelief, so I welcome any evidence against this.

Related

Nancy Exception in RequestStartup

I'm using Nancy to create a web api. I have a signed token that is passed in from the user to authenticate. This authentication is doen in the RequestStartup method in my own Bootstrapper. Now in some cases, for instance when I can't veryfy the signed token I would like to just be able to throw an exception and have that handled byt the OnError hanhdler in Nancy. However an exception thrown before the RequestStartup is finsihed isn't caught. The request generates a 500 error and I would like to return something else with my own error information.
I have the obvious case where I throw an exception but also possibilities of an exception being thrown in the GetIdentity() method.
I'm looking for any input in how to handle this.
protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
{
base.RequestStartup(container, pipelines, context);
pipelines.OnError.AddItemToStartOfPipeline((ctx, exception) =>
container.Resolve<IErrorHandler>().HandleException(ctx, exception));
var identity = container.Resolve<IAuthenticationController>().GetIdentity();
var configuration = new StatelessAuthenticationConfiguration(_ => identity);
StatelessAuthentication.Enable(pipelines, configuration);
var logManager = new LogManager(context);
pipelines.AfterRequest.AddItemToEndOfPipeline(_ => logManager.Log());
try
{
X509Certificate2 clientCert = context.Request.ClientCertificate as X509Certificate2;
container.Resolve<ICertificateValidator>().Validate(clientCert);
}
catch (Exception ex)
{
throw new MklServerAuthenticationException(ErrorCodes.WrongOrNonexistingCertificate, ex);
}
}
Figured out a way to solve the above problem and thought somebody else might like to know. Replace the line in my code above, containing the GetIdentity() call, with the following:
Identity identity = null;
try
{
identity = container.Resolve<IAuthenticationController>().GetIdentity(requestInfo);
}
catch (Exception ex)
{
var exception = new MklAuthentcationException(ErrorCodes.TokenInvalid, ex);
context.Response = container.Resolve<IErrorHandler>().HandleException(context, exception);
pipelines.BeforeRequest.Invoke(context, CancellationToken.None);
}
I'm using the fact stated in nancy that:
The PreRequest hook is called prior to processing a request. If a hook returns a non-null response then processing is aborted and the response provided is returned.
So by setting a response (my error in this case) on the PreRequest hook and invoking it my error is returned and execution is stopped.
Maybe not the nicest solution... If you can figure out something better please let me know.

ws how to catch : WebSocket connection to 'ws:// failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

i have simple web sockets html5 , when the server is up every thing is working fine
the problem is when i close the server ( for testing )
im getting :
WebSocket connection to 'ws://127.0.0.1:7777/api' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
which i unable to catch its never jumps to onerror or onclose in case of this error
init: function () {
this.m_wsiSendBinary = new WebSocket("ws://127.0.0.1:7681/wsapi");
this.m_wsiSendBinary.onopen = function(evt) {
cc.log("Send Binary WS was opened.");
};
this.m_wsiSendBinary.onmessage = (function(evt) {
this.handleServerResponse(yStr);
this.m_wsiSendBinary.onerror = function(evt) {
};
this.m_wsiSendBinary.onclose = function(evt) {
cc.log("m_wsiSendBinary websocket instance closed.");
self.m_wsiSendBinary = null;
};
}).bind(this);
I do not have full answer, however I dealt with similar issue and have a partial and not so elegant solution (but may help someone). Unfortunately without the elimination of the error message.
Two business requirements:
BR1 - Handle state in initialization when the server is not available.
BR2 - Handle state when the server stops.
Solution for BR1
var global_connection_openned=null;//Here you have the result
init: function () {
global_connection_openned=false;
this.m_wsiSendBinary = new WebSocket("ws://127.0.0.1:7681/wsapi");
this.m_wsiSendBinary.onopen = function(evt)
{
global_connection_openned=true;
};
Solution for BR2 (assumes the BR1)
//somewhere in your project called by setInterval(..) which will detect the connection is lost (and tries to reestablish/reopen the connetion.
{
if (this.m_wsiSendBinary==null || this.m_wsiSendBinary.readyState==3)
this.init();
if (!global_connection_openned)
this.m_wsiSendBinary=null;
}
Anyway, I would be really curious if there is solid and proper solution of this use case.

URLLoader Throwing Uncatcheable ioError when No Internet Connection

Flash is throwing an uncatchable exception when using a URLLoader with no internet connection:
Error #2044: Unhandled ioError:. text=Error #2032: Stream Error
Since I'm developing a phone app, there's always a chance the internet will drop. I want to detect this and show an error dialog. Is there anyway to catch and suppress this error? Code follows:
try
{
var request:URLRequest = new URLRequest(API_URL + "/" + API_VERSION + "/" + gameKey + "/" + type);
request.data = jsonString;
request.method = URLRequestMethod.POST;
request.requestHeaders.push(new URLRequestHeader("Authorization", MD5.hash(jsonString + secretKey)));
var loader:URLLoader = new URLLoader();
loader.data = type;
loader.addEventListener(Event.COMPLETE, onRequestComplete);
loader.addEventListener(IOErrorEvent.IO_ERROR, onRequestError);
loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onRequestSecurityError);
loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onRequestStatus);
loader.load(request);
} catch (Error) { trace("URLLoader Failed");}
The exception stack claims the it is raised on the line where the URLLoader is allocated, but while debugging execution runs past that line, and the exception comes from an unknown place. The catch block is never invoked. The error event handlers are hit, but only AFTER the exception is shown as being un-handled by the Flash Player.
Any help would be appreciated. I'm tearing my hair out and can't find the answer online (other people have reported the same problem but there are no solutions.)
Flash is throwing an uncatchable exception when using a URLLoader with no internet connection
To catch them, go with uncaughtErrorEvents in LoaderInfo. For example you could subscribe for the uncaught errors and manage them with some fallback logic:
//Somewhere, you could manage it globally, or declare before risky part
loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onUncaughtError);
private function onUncaughtError(e:UncaughtErrorEvent):void {
e.preventDefault();
trace("Scorpion: come here! - " + e.toString());
}

AS3 LocalConnection Errors

Not sure where I'm going wrong, for now just trying this out locally. Thanks.
sendingLC.swf does return, LocalConnection.send() succeeded
This is the errors I get from Flash.
Error #2044: Unhandled AsyncErrorEvent:. text=Error #2095: flash.net.LocalConnection was unable to invoke callback myMethod. error=ReferenceError: Error #1069: Property myMethod not found on flash.net.LocalConnection and there is no default value.
Code for sendingLC.swf:
import flash.net.LocalConnection
var sendingLC:LocalConnection;
sendingLC = new LocalConnection();
sendingLC.allowDomain('*');
Security.allowDomain("*");
sendBtn.addEventListener(MouseEvent.CLICK, sendIt);
function sendIt(eventObj:MouseEvent):void {
sendingLC.send('myConnection', 'myMethod');
}
sendingLC.addEventListener(StatusEvent.STATUS, statusHandler);
function statusHandler (event:StatusEvent):void
{
switch (event.level)
{
case "status" :
textArea.text = ("LocalConnection.send() succeeded");
break;
case "error" :
textArea.text = ("LocalConnection.send() failed");
break;
}
}
Code for receivingLC.swf:
import flash.net.LocalConnection
var receivingLC:LocalConnection;
receivingLC = new LocalConnection();
receivingLC.allowDomain('*');
Security.allowDomain("*");
receivingLC.connect('myConnection');
function myMethod():void {trace('Hello World')}
I also had issues with the LocalConnection giving me callback errors, but it stopped when I added the client property to the connection. Then it started working, even in flash IDE.
var conn:LocalConnection;
conn = new LocalConnection();
conn.allowDomain('*');
conn.client = this;
conn.connect('localThingieConnector');
There could be an issue with making the connection in the receiver.
try {
var receivingLC:LocalConnection;
receivingLC = new LocalConnection();
receivingLC.allowDomain('*');
Security.allowDomain("*"); // not sure this line is needed
receivingLC.connect('myConnection');
} catch (error:ArgumentError) {
trace('failure to make connection ' + error.toString() );
}
Also something to note do not test LocalConnections in the flash api do it through a browser when you are first making these as permission issues can be a cranky woman.
Perhaps try making myMethod public like so:
public function myMethod():void{
trace("hello world");
}
Also you should try/catch the send call so you get more information about errors like so:
try{
sendingLC.send('myConnection', 'myMethod');
}
catch(e:Error){
trace(e.toString());
}

How to catch http client request exceptions in node.js

I've got a node.js app that I want to use to check if a particular site is up and returning the proper response code. I want to be able to catch any errors that come up as the domain name isn't resolving or the request is timing out. The problem is is that those errors cause Node to crap out. I'm new to this whole asynchronous programming methodology, so I'm not sure where to put my try/catch statements.
I have an ajax call that goes to something like /check/site1. Server side that calls a function which attempts to make a connection and then return the statusCode. It's a very simple function, and I've wrapped each line in a try/catch and it never catches anything. Here it is:
function checkSite(url){
var site = http.createClient(80, url);
var request = site.request('GET', '/', {'host': url});
request.end();
return request;
}
Even with each of those lines wrapped in a try/catch, I will still get uncaught exceptions like EHOSTUNREACH and so on. I want to be able to catch those and return that to the ajax call.
Any recommendations on what to try next?
http.createClient has been deprecated.
Here is a quick example of how to handle errors using the new http.request:
var http = require("http");
var options = {
host : "www.example.com"
};
var request = http.request(options, function(req) {
...
});
request.on('error', function(err) {
// Handle error
});
request.end();
Unfortunately, at the moment there's no way to catch these exceptions directly, since all the stuff happens asynchronously in the background.
All you can do is to catch the uncaughtException's on your own:
var http = require('http');
function checkSite(url){
var site = http.createClient(800, url);
var request = site.request('GET', '/', {'host': url});
request.end();
return request;
}
process.on('uncaughtException', function (err) {
console.log(err);
});
checkSite('http://127.0.0.1');
Which in this case (notice port 800) logs:
{ message: 'ECONNREFUSED, Connection refused',
stack: [Getter/Setter],
errno: 111,
syscall: 'connect' }
Node.js is still under heavy development and there sure will be a lot of progress in the next couple of months, right now focus seem to be on fixing performance bugs for 3.x and making the API somewhat stable, because after all Node.js is mainly a server so throughput matters.
You can file a bug though, but be warned crashes etc. have way higher priority than features, and most new features make it in via fork pull requests.
Also for the current Roadmap of Node.js watch this talk by Ryan Dahl (Node's Creator):
http://developer.yahoo.com/yui/theater/video.php?v=yuiconf2010-dahl
I stumbled across another solution while I was researching a similar problem. http.Client emits an 'error' event if a connection can't be established for any reason. If you handle this event then the exception won't be thrown:
var http = require('http');
var sys = require('sys');
function checkSite(url) {
var site = http.createClient(80, url);
site.on('error', function(err) {
sys.debug('unable to connect to ' + url);
});
var request = site.request('GET', '/', {'host': url});
request.end();
request.on('response', function(res) {
sys.debug('status code: ' + res.statusCode);
});
}
checkSite("www.google.com");
checkSite("foo.bar.blrfl.org");
Of course, the connection error and the response to the request both arrive asynchronously, meaning that simply returning the request won't work. Instead, you'd have to notify the caller of the results from within the event handlers.
Actually it's even easier that the accepted answer:
function checkSite(url){
var http = require('http');
var request = http.get(url,r=>{console.log("OK",r)}).on("error",e=>{
console.log("ERROR",e)
})
}