Why does `websocket.close()` before connection establishes triggers `onerror`? - javascript

Calling websocket.close() before connection is established triggers onerror. I wasn't able to figure out what the error is, nor where it came from.
const connection = new WebSocket("wss://echo.websocket.org");
connection.onopen = () => {
console.log('open');
}
connection.onerror = (error) => {
throw error; // this is thrown
}
connection.close();
Tested in chrome dev console. onerror is being triggered when close is called.
If I wait until the connection is established before calling close, no error is thrown. I wonder what the error is
Edit:
included the error output:

I took my own advice and checked it out - and it gave me this:
Not sure if that answers your question if I say that it's more strange not to expect an error when you're not waiting for a connection before closing a socket.
Just handle it with a try-catch or put your connection.close() inside your onopen handler?

Related

A way to stop WebSocket errors to show up in browser's console

So the problem is when I try to initiate a new WebSocket to a remote host, sometimes the browser's console prints a red error message and complains about a refused connection, here is the message:
Error in connection establishment: net::ERR_CONNECTION_REFUSED
Having an error is fine since the remote host might be not responding sometimes, but the fact that I cannot handle this error message is very annoying.
Is there any way to either handle this error message or check whether the remote host accepts the WebSocket connection before initializing one in my JavaScript code??
Several possibilities come to mind:
Add a WebSocket.onerror error handler
myWebSocket.onerror = myEventHandler;
Wrap your "connect" in a try/catch block
try {
const connection = new WebSocket(myUrl);
...
}
catch(error) {
console.error(error);
}
Structure your code such that your I/O is event driven:
https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#Examples
// Create WebSocket connection.
const socket = new WebSocket('ws://localhost:8080');
// Connection opened
socket.addEventListener('open', function (event) {
socket.send('Hello Server!');
});
// Listen for messages
socket.addEventListener('message', function (event) {
console.log('Message from server ', event.data);
});
// Handle errors
socket.addEventListener('error', function (event) {
console.log('WebSocket error observed:', event);
});
ADDENDUM:
The above methods allow you to completely handle a websockets exception.
Regardless of whether the exception is handled or not, the Chrome debugger will tell you if an exception has occurred. This is a Good Thing. It's called a "First-Chance Exception":
https://learn.microsoft.com/en-us/security-risk-detection/concepts/first-chance-exception
.. it is known a “first chance” exception – the debugger is given the
first chance of inspecting the exception prior to the application
handling it (or not).
In Microsoft's Visual Studio debugger, there's a little checkbox you can use to "gag" first chance exceptions. I'm not aware of any similar "checkbox" in Chrome debugger.
POSSIBLE SUGGESTIONS:
Chrome debugger has a "filter". EXAMPLE FILTER REGEX: ^((?!ERR_CONNECTION_REFUSED).)*$
This link suggests you might be able to use the filter to "Hide Network Messages" (I haven't tried it myself). See also this link.

How do I find out if connectNative failed or succeeded

I have managed to connect my extension to our native host:
var pulse_tracker_port = chrome.runtime.connectNative('com.cloudfactory.pulsetracker');
but how do I find out if the connection succeeded or not? The value of 'pulse_tracker_report.name' will always be an empty string no matter if the connection succeeded or not.
I also tried to add listeners to find out if the connection succeeded or not but none of these callbacks are being invoked:
chrome.runtime.onConnect.addListener(function(port)
{
console.log('Connected to "Pulse Tracker" #port: ' + port.name);
});
chrome.runtime.onConnectExternal.addListener(function(port)
{
console.log('Connected to "Pulse Tracker" #port: ' + port.name);
});
BTW this won't be invoked either:
pulse_tracker_port.onConnect.addListener(function(port)
{
console.log('Connected to "Pulse Tracker" #port: ' + port.name);
});
This is what I get when I try to do so:
main.js:26 Uncaught TypeError: Cannot read property 'addListener' of undefined
onConnectExternal works for cross-extension messaging between extensions but looks like it doesn't work for native message hosting. Any help would be appreciated. Thanks
chrome.runtime.onConnect and chrome.runtime.onConnectExternal are not relevant here, since they notify you about incoming connections, not about state of outgoing connections.
pulse_tracker_port is a Port object which does not have onConnect property.
What you need to do is to immediately assign a listener to onDisconnect event of the port object. If there was a problem with the connection, the listener will be called and chrome.runtime.lastError will be set:
var pulse_tracker_port = chrome.runtime.connectNative('com.cloudfactory.pulsetracker');
pulse_tracker_port.onDisconnect.addListener(function() {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError);
}
});
Otherwise, just try to use it, with .postMessage() and .onMessage event. For postMessage, it will throw an error if the port is disconnected.

Cancel WebSocket connection when trying to connect (JavaScript)

Is it possible to cancel WebSocket connection while trying to establish connection to the server?
Let's say user notified that it is a misspelled host and want to cancel request for establishing connection before onerror has raised like
failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
I tried to call close, but this does not cancel request. I even get warning in console:
failed: WebSocket is closed before the connection is established.
Unfortunately, this is not achievable using close(), and seems not possible at all.
Also, unlike XMLHttpRequest, WebSocket have no abort method to achieve this.
The WebSocket specs do not mention any way of doing this, and setting the object to null does not do the trick.
The following example illustrates this by setting the WebSocket object to null, but still getting connection error message.
var ws = new WebSocket('ws://unknownhost.local');
ws.onopen = function() {
console.log('ohai');
};
ws = null;
console.log(ws);
// > null
// > VM2346:35 WebSocket connection to 'ws://unknownhost.local/' failed: Error in connection establishment: net::ERR_NAME_NOT_RESOLVED
Since the two previous answers to this question have been posted the behaviour of close() seems to have changed.
Quoting the mozilla API docs:
The WebSocket.close() method closes the WebSocket connection or connection attempt, if any. If the connection is already CLOSED, this method does nothing.
You could therefore do this:
var ws = new WebSocket('ws://unknownhost.local');
setTimeout(() => {
if (ws.readyState == WebSocket.CONNECTING) {
ws.close();
console.log("Connection cancelled.");
}
}, 1000);
Which would cancel the connection attempt if the readyState did not switch to OPEN yet.
I tried this, and it seems to work (tested on Firefox).
close() method only terminates the established connections.
For your case, you may use assigning your websocket handle to null where you want to stop it.
webSocketHanle = null;
By this assignment, your callbacks will not be activated.
But notice that it is quite fast process to getting response from server.

Why am i getting this error running 'net' module node.js

I am using .net modular and opening tcp port on 6112.
var net = require('net');
var server = net.createServer(function (socket) { //'connection' listener
});
server.listen(6112, function () { //'listening' listener
console.log('server started');
});
On the same machine i start a java socket in main.
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
System.out.println("Connecting...");
Socket socket = new Socket("localhost", 6112);
System.out.println("Connected");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I get this exception,
C:\Users\Mustafa\WebstormProjects\Node.Js>node hello.js
server started
events.js:72
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at errnoException (net.js:884:11)
at TCP.onread (net.js:539:19)
Is this like a bug or something, cause if once i get through this bug, I will be good thanks.
I haven't used the debugger cause as Ryan said it him self a year ago that it is still shitt.
You need to listen for errors on the socket. Node has the default behavior that when something does .emit('error'), if there are no error handlers attached, it will throw the error instead, thus crashing the application.
var server = net.createServer(function (socket) {
socket.on('error', function(err){
// Handle the connection error.
});
});
You are creating a socket and connecting from it, but not closing it. So when the program finishes, to node.js it looks like connection is reset (closed abruptly). Call socket.close(); before program finishes.
You can structure your code in this way :
try {
tryStatements //your code that is causing exceptions
}
catch(exception){
catchStatements //handle caught exceptions
}
finally {
finallyStatements //execute it anyways
}
Or if you like to catch uncaught exceptions from runtime, use this (main process won't exit on exceptions)
process.on('uncaughtException', function(err) {
console.log('Caught exception: ' + err);
console.log(err.stack);
});
The problem is in java code which is causing node.js to exit on exception. So be sure to add socket.close();. Above is just error handling on node.js part.

Error in Javascript causes page in IE to stop running javascript

On my website, I have a reference to a javascript file, and on IE, this error is thrown:
send: function (data) {
/// <summary>Sends data over the connection</summary>
/// <param name="data" type="String">The data to send over the connection</param>
/// <returns type="signalR" />
var connection = this;
if (!connection.transport) {
// Connection hasn't been started yet
throw "SignalR: Connection must be started before data can be sent. Call .start() before .send()";
}
connection.transport.send(connection, data);
return connection;
},
That throw is being caught by Internet Explorer, and it appears to halt any other javascript from running.
What can I do so that error doesn't completely halt everything on my page?
Why are you using throw if you don't want to throw the exception?
consider this, if you want the exception for logging purposes:
if (!connection.transport) {
// Connection hasn't been started yet
setTimeout(function() {
throw "SignalR: Connection must be started before data can be sent. Call .start() before .send()";
}, 0);
return;
}

Categories

Resources