Javascript не улавливает ошибку в создании экземпляра WebSocket
Мой сокет в настоящее время выбрасывает net::ERR_CONNECTION_REFUSED, потому что сервер не работает, что я хочу сделать в данный момент.
Проблема в том, что следующий фрагмент кода не улавливает ошибку. В консоли я вижу исключение в строке 2 (с net::ERR_CONNECTION_REFUSED), которое, по моему мнению, не должно происходить, поскольку оно находится внутри оператора try.
1 try {
2 ws = new WebSocket('ws://'+ host + ':' + port + '/');
3 }
4 catch (err) {
5 console.log('This never prints');
6 }
7 ws.onerror = function (error) {
8 console.log(error);
9 };
Итак, мой вопрос: почему его не поймали?
В конечном итоге я хочу, чтобы сообщение об ошибке отображалось в другом месте, но я не могу его перехватить, и в строке 8 выводится объект "событие", в котором нет упоминания net::ERR_CONNECTION_REFUSED, поэтому я не уверен, как получить сообщение об ошибке.
4 ответа
WebSocket
Ошибка времени соединения вызывает отправленное событие, а не выброшенное значение. Это потому что throw
операции должны быть синхронными. Чтобы обработать все ошибки времени соединения как выданные ошибки, WebSocket
Конструктор должен будет полностью приостановить выполнение всех сценариев и взаимодействие с пользовательским интерфейсом, пока не будет завершено полное рукопожатие WebSocket. Вместо этого процесс подключения выполняется асинхронно, что позволяет потоку браузера продолжать работать, пока подключение WebSocket инициализируется в фоновом режиме. Из-за асинхронного характера соединения WebSocket
должен сообщать об ошибках через error
события, так как синхронные new WebSocket
операция уже завершена к тому времени, когда в задаче асинхронного соединения обнаружена ошибка.
ERR_CONNECTION_REFUSED
сообщение, которое вы видите, чисто для блага разработчиков; это не доступно для сценария в любом случае. Он не имеет представления в среде JavaScript. Это просто сообщение красного цвета, которое появляется в вашей консоли, чтобы сообщить вам, человеку, смотрящему в браузер, об ошибке.
error
Событие-обработчик - правильное место для ответа на сбой, но отсутствие читаемой сценарием информации об ошибке времени соединения является преднамеренным. Из спецификации WHATWG для API WebSocket:
Пользовательские агенты не должны передавать какую-либо информацию об ошибках в сценарии таким образом, чтобы сценарий мог различать следующие ситуации:
- Сервер, имя хоста которого не может быть разрешено.
- Сервер, на который невозможно успешно перенаправить пакеты.
- Сервер, который отклонил соединение на указанном порту.
- Сервер, который не смог правильно выполнить квитирование TLS (например, сертификат сервера не может быть проверен).
- Сервер, который не завершил открывающее рукопожатие (например, потому что это не был сервер WebSocket).
- Сервер WebSocket, который отправил правильное открывающее рукопожатие, но в котором указаны параметры, которые заставили клиента разорвать соединение (например, сервер указал подпротокол, который клиент не предлагал).
- Сервер WebSocket, который внезапно закрыл соединение после успешного завершения рукопожатия при открытии.
[...] Разрешение сценарию различать эти случаи позволило бы сценарию проверять локальную сеть пользователя при подготовке к атаке.
Браузер намеренно пропускает любую полезную информацию, как того требует спецификация. Авторы спецификаций обеспокоены тем, что доступ к этой информации может позволить вредоносной веб-странице получить информацию о вашей сети, поэтому они требуют, чтобы браузеры сообщали обо всех ошибках во время соединения неразличимым образом.
Браузеры на базе Chrome: в моем случае я просто хотел избавиться от сообщения об ошибке из консоли. В этом случае вы можете ввести это регулярное выражение в фильтр консоли:
-/Websocket\sconnection.*failed/
const socket = new WebSocket('ws://HOST:PORT'); // create websocket instance
socket.addEventListener('error', (event) => { /* do something */ });
// or the same
socket.onerror = (event) => { /* do something */ };
Я попытался создать скрипку с этим, и я могу видеть напечатанную линию.
host='localhost';
port=100;
try {
ws = new WebSocket('ws://'+ host + ':' + port + '/');
}
catch (err) {
console.log('This never prints');
}
ws.onerror = function (error) {
console.log(error);
};