Node version: 12,16.2
Sails version _(sails)_: 1.2.4
ORM hook version _(sails-hook-orm)_:
Sockets hook version _(sails-hook-sockets)_: 1.2.1
Organics hook version _(sails-hook-organics)_:
Grunt hook version _(sails-hook-grunt)_:
Uploads hook version _(sails-hook-uploads)_:
DB adapter & version _(e.g. [email protected])_:
Skipper adapter & version _(e.g. [email protected])_:
There is no error handler for the jsonp request to the server's __getcookie. This means there is no way to signal via socket events that this method failed and a connection cannot / will not be established.
An example: My sails.js server is currently in the process of renewing the SSL certificate. The current one just expired. The __getcookie request from sails.io fails with certificate invalid. However, the error is simply thrown in the console; no socket events are fired to indicate the connection failed and the socket will not connect. Therefore, I am unable to provide the user with a connection failed error screen on the web page.
The error occurs on line 517:
document.getElementsByTagName('head')[ 0 ].appendChild(scriptEl);
A try / catch block for this line does not seem to work, nor does it work where jsonp is called. This is probably because the error occurs within the scope of the created script tag.
For this reason, I don't know if any resolution can be made (that is beyond me). But it would be a lifesaver if it could.
Edit: ...come to think of it, perhaps there should be a better way to handle all cases where the jsonp ends up not calling the internal function to continue the connection (bad URL, no internet, SSL problem, server down, etc). If it fails for any reason, none of the socket event handlers are called since the socket is not initialized. Therefore, the error cannot be properly handled.
Edit2: A setTimeout is also complicated, it seems, especially since __getcookie would fail before the socket is even initialized by io (and therefore the socket event handlers cannot be used).
@Lovinity Thanks for posting! We'll take a look as soon as possible.
In the mean time, there are a few ways you can help speed things along:
Please remember: never post in a public forum if you believe you've found a genuine security vulnerability. Instead, disclose it responsibly.
For help with questions about Sails, click here.
Some food for thought.
try/catch can't work because the script is loaded asynchronously. The HTTP error will happen some time in the future after the function that inserts the script tag has completed.
_sailsIoJSConnect, and by proxy cb, will never be called because the __getcookie response doesn't return anything useful to call it so the socket connection stuff will never start (because cb never gets called).
Maybe an error handler could be added to scriptEl around here before it's inserted into the DOM for situations like these.
scriptEl.addEventListener('error', function (err) {
alert('boom');
console.error(err);
// But IRL do something useful here
})
There's some vague hints on error handling dynamic script tags on MDN https://developer.mozilla.org/en-US/docs/Web/API/HTMLScriptElement#Dynamically_importing_scripts
@nahanil Sweet. Thanks for the information; I had no idea script tags had error handlers. The problem though is getting that error to be passed to the renderer javascript. This error handler exists within sails.io.js, but I somehow need to get this error passed to the javascript which initiated the socket via io.sails.connect. Since the socket isn't initialized yet, I can't emit a socket event. Is there perhaps a way to do an io.sails.on?
Hey, @Lovinity! To connect to the socket, are you explicitly calling connect(), or are you using auto-connect?
@madisonhicks I'm using connect() because server requires an auth query to be sent upon connection (handled by sails.js beforeConnect).
Thanks for your patience, @Lovinity!
Maybe we could add a new method called connectCarefully()鈥攁n async function鈥攚hich, when used with await or .then() chaining, would allow that kind of error handling. What do you think?
That sounds like it could definitely work, since connectCarefully would be called in renderer, and the then() chain can provide an error, allowing me to display an error message to the user.