Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2024)

Unified Diff: Source/modules/websockets/MainThreadWebSocketChannel.cpp

Issue 14657008: Make websocket error messages look better at the devtools console. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/modules/websockets/MainThreadWebSocketChannel.h ('k') | Source/modules/websockets/WebSocket.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/modules/websockets/MainThreadWebSocketChannel.cpp
diff --git a/Source/modules/websockets/MainThreadWebSocketChannel.cpp b/Source/modules/websockets/MainThreadWebSocketChannel.cpp
index 6be6fff378ca86dc388272a4e7efc7a40b8320ff..11b8540f6c80027acdd63f490145faa64af15944 100644
--- a/Source/modules/websockets/MainThreadWebSocketChannel.cpp
+++ b/Source/modules/websockets/MainThreadWebSocketChannel.cpp
@@ -72,7 +72,7 @@ namespace WebCore {
const double TCPMaximumSegmentLifetime = 2 * 60.0;
-MainThreadWebSocketChannel::MainThreadWebSocketChannel(Document* document, WebSocketChannelClient* client)
+MainThreadWebSocketChannel::MainThreadWebSocketChannel(Document* document, WebSocketChannelClient* client, const ScriptCallFrame& callFrame)
: m_document(document)
, m_client(client)
, m_resumeTimer(this, &MainThreadWebSocketChannel::resumeTimerFired)
@@ -89,7 +89,7 @@ MainThreadWebSocketChannel::MainThreadWebSocketChannel(Document* document, WebSo
, m_closeEventCode(CloseEventCodeAbnormalClosure)
, m_outgoingFrameQueueStatus(OutgoingFrameQueueOpen)
, m_blobLoaderStatus(BlobLoaderNotStarted)
- , m_callFrameAtConnection("", "", 0)
+ , m_callFrameAtConnection(callFrame)
{
if (Page* page = m_document->page())
m_identifier = createUniqueIdentifier();
@@ -113,8 +113,9 @@ void MainThreadWebSocketChannel::connect(const KURL& url, const String& protocol
InspectorInstrumentation::didCreateWebSocket(m_document, m_identifier, url, m_document->url(), protocol);
ref();
m_handle = SocketStreamHandle::create(m_handshake->url(), this);
- RefPtr<ScriptCallStack> callstack = createScriptCallStack(1, true);
- m_callFrameAtConnection = callstack && callstack->size() > 0 ? callstack->at(0) : ScriptCallFrame("", "", 0);
+ RefPtr<ScriptCallStack> callStack = createScriptCallStack(1, true);
+ if (callStack && callStack->size() > 0)
+ m_callFrameAtConnection = callStack->at(0);
}
String MainThreadWebSocketChannel::subprotocol()
@@ -197,27 +198,43 @@ void MainThreadWebSocketChannel::close(int code, const String& reason)
m_closingTimer.startOneShot(2 * TCPMaximumSegmentLifetime);
}
-void MainThreadWebSocketChannel::fail(const String& reason)
+void MainThreadWebSocketChannel::fail(const String& reason, MessageLevel level)
+{
+ fail(reason, level, PassOwnPtr<CallStackWrapper>());
+}
+
+void MainThreadWebSocketChannel::fail(const String& reason, MessageLevel level, PassOwnPtr<CallStackWrapper> wrapper)
{
LOG(Network, "MainThreadWebSocketChannel %p fail() reason='%s'", this, reason.utf8().data());
ASSERT(!m_suspended);
if (m_document) {
InspectorInstrumentation::didReceiveWebSocketFrameError(m_document, m_identifier, reason);
const String message = "WebSocket connection to '" + m_handshake->url().elidedString() + "' failed: " + reason;
- RefPtr<ScriptCallStack> callstack = createScriptCallStack(1, true);
- if (callstack && callstack->size() > 0) {
- // We are in a JS callstack.
- // So, the addConsoleMessage method will show the stack appropriately.
- m_document->addConsoleMessage(JSMessageSource, ErrorMessageLevel, message);
+ RefPtr<ScriptCallStack> callStack = wrapper ? wrapper->createCallStack() : 0;
+ if (callStack && callStack->size() > 0) {
+ String url = callStack->at(0).sourceURL();
+ unsigned lineNumber = callStack->at(0).lineNumber();
+ static_cast<ScriptExecutionContext*>(m_document)->addConsoleMessage(JSMessageSource, level, message, url, lineNumber);
} else {
- // We are not in a JS callstack.
- // Then show the source file and the line number at the connection initiation.
- const String& url = m_callFrameAtConnection.sourceURL();
- unsigned lineNumber = m_callFrameAtConnection.lineNumber();
- static_cast<ScriptExecutionContext*>(m_document)->addConsoleMessage(JSMessageSource, ErrorMessageLevel, message, url, lineNumber, 0, 0);
+ RefPtr<ScriptCallStack> callStack = createScriptCallStack(1, true);
+ if (callStack && callStack->size() > 0) {
+ // We are in a JS callstack.
+ // So, the addConsoleMessage method will show the stack appropriately.
+ m_document->addConsoleMessage(JSMessageSource, level, message);
+ } else {
+ // We are not in a JS callstack.
+ // Then show the source file and the line number at the connection initiation.
+ const String& url = m_callFrameAtConnection.sourceURL();
+ unsigned lineNumber = m_callFrameAtConnection.lineNumber();
+ static_cast<ScriptExecutionContext*>(m_document)->addConsoleMessage(JSMessageSource, level, message, url, lineNumber);
+ }
}
}
+ failInternal();
+}
+void MainThreadWebSocketChannel::failInternal()
+{
// Hybi-10 specification explicitly states we must not continue to handle incoming data
// once the WebSocket connection is failed (section 7.1.7).
RefPtr<MainThreadWebSocketChannel> protect(this); // The client can close the channel, potentially removing the last reference.
@@ -280,7 +297,7 @@ void MainThreadWebSocketChannel::didOpenSocketStream(SocketStreamHandle* handle)
InspectorInstrumentation::willSendWebSocketHandshakeRequest(m_document, m_identifier, *m_handshake->clientHandshakeRequest());
CString handshakeMessage = m_handshake->clientHandshakeMessage();
if (!handle->send(handshakeMessage.data(), handshakeMessage.length()))
- fail("Failed to send WebSocket handshake.");
+ failAsError("Failed to send WebSocket handshake.");
}
void MainThreadWebSocketChannel::didCloseSocketStream(SocketStreamHandle* handle)
@@ -328,7 +345,7 @@ void MainThreadWebSocketChannel::didReceiveSocketStreamData(SocketStreamHandle*
return;
if (!appendToBuffer(data, len)) {
m_shouldDiscardReceivedData = true;
- fail("Ran out of memory while receiving WebSocket data.");
+ failAsError("Ran out of memory while receiving WebSocket data.");
return;
}
while (!m_suspended && m_client && !m_buffer.isEmpty())
@@ -399,7 +416,7 @@ void MainThreadWebSocketChannel::didFail(int errorCode)
ASSERT(m_blobLoaderStatus == BlobLoaderStarted);
m_blobLoader.clear();
m_blobLoaderStatus = BlobLoaderFailed;
- fail("Failed to load Blob: error code = " + String::number(errorCode)); // FIXME: Generate human-friendly reason message.
+ failAsError("Failed to load Blob: error code = " + String::number(errorCode)); // FIXME: Generate human-friendly reason message.
deref();
}
@@ -462,7 +479,7 @@ bool MainThreadWebSocketChannel::processBuffer()
LOG(Network, "MainThreadWebSocketChannel %p Connection failed", this);
skipBuffer(headerLength);
m_shouldDiscardReceivedData = true;
- fail(m_handshake->failureReason());
+ failAsError(m_handshake->failureReason());
return false;
}
if (m_handshake->mode() != WebSocketHandshake::Connected)
@@ -526,7 +543,7 @@ bool MainThreadWebSocketChannel::processFrame()
if (result == WebSocketFrame::FrameIncomplete)
return false;
if (result == WebSocketFrame::FrameError) {
- fail(errorString);
+ failAsError(errorString);
return false;
}
@@ -535,47 +552,47 @@ bool MainThreadWebSocketChannel::processFrame()
OwnPtr<InflateResultHolder> inflateResult = m_deflateFramer.inflate(frame);
if (!inflateResult->succeeded()) {
- fail(inflateResult->failureReason());
+ failAsError(inflateResult->failureReason());
return false;
}
if (!m_perMessageDeflate.inflate(frame)) {
- fail(m_perMessageDeflate.failureReason());
+ failAsError(m_perMessageDeflate.failureReason());
return false;
}
// Validate the frame data.
if (WebSocketFrame::isReservedOpCode(frame.opCode)) {
- fail("Unrecognized frame opcode: " + String::number(frame.opCode));
+ failAsError("Unrecognized frame opcode: " + String::number(frame.opCode));
return false;
}
if (frame.compress || frame.reserved2 || frame.reserved3) {
- fail("One or more reserved bits are on: reserved1 = " + String::number(frame.compress) + ", reserved2 = " + String::number(frame.reserved2) + ", reserved3 = " + String::number(frame.reserved3));
+ failAsError("One or more reserved bits are on: reserved1 = " + String::number(frame.compress) + ", reserved2 = " + String::number(frame.reserved2) + ", reserved3 = " + String::number(frame.reserved3));
return false;
}
if (frame.masked) {
- fail("A server must not mask any frames that it sends to the client.");
+ failAsError("A server must not mask any frames that it sends to the client.");
return false;
}
// All control frames must not be fragmented.
if (WebSocketFrame::isControlOpCode(frame.opCode) && !frame.final) {
- fail("Received fragmented control frame: opcode = " + String::number(frame.opCode));
+ failAsError("Received fragmented control frame: opcode = " + String::number(frame.opCode));
return false;
}
// All control frames must have a payload of 125 bytes or less, which means the frame must not contain
// the "extended payload length" field.
if (WebSocketFrame::isControlOpCode(frame.opCode) && WebSocketFrame::needsExtendedLengthField(frame.payloadLength)) {
- fail("Received control frame having too long payload: " + String::number(frame.payloadLength) + " bytes");
+ failAsError("Received control frame having too long payload: " + String::number(frame.payloadLength) + " bytes");
return false;
}
// A new data frame is received before the previous continuous frame finishes.
// Note that control frames are allowed to come in the middle of continuous frames.
if (m_hasContinuousFrame && frame.opCode != WebSocketFrame::OpCodeContinuation && !WebSocketFrame::isControlOpCode(frame.opCode)) {
- fail("Received new data frame but previous continuous frame is unfinished.");
+ failAsError("Received new data frame but previous continuous frame is unfinished.");
return false;
}
@@ -585,7 +602,7 @@ bool MainThreadWebSocketChannel::processFrame()
case WebSocketFrame::OpCodeContinuation:
// An unexpected continuation frame is received without any leading frame.
if (!m_hasContinuousFrame) {
- fail("Received unexpected continuation frame.");
+ failAsError("Received unexpected continuation frame.");
return false;
}
m_continuousFrameData.append(frame.payload, frame.payloadLength);
@@ -606,7 +623,7 @@ bool MainThreadWebSocketChannel::processFrame()
else
message = "";
if (message.isNull())
- fail("Could not decode a text frame as UTF-8.");
+ failAsError("Could not decode a text frame as UTF-8.");
else
m_client->didReceiveMessage(message);
} else if (m_continuousFrameOpCode == WebSocketFrame::OpCodeBinary)
@@ -623,7 +640,7 @@ bool MainThreadWebSocketChannel::processFrame()
message = "";
skipBuffer(frameEnd - m_buffer.data());
if (message.isNull())
- fail("Could not decode a text frame as UTF-8.");
+ failAsError("Could not decode a text frame as UTF-8.");
else
m_client->didReceiveMessage(message);
} else {
@@ -655,7 +672,7 @@ bool MainThreadWebSocketChannel::processFrame()
m_closeEventCode = CloseEventCodeNoStatusRcvd;
else if (frame.payloadLength == 1) {
m_closeEventCode = CloseEventCodeAbnormalClosure;
- fail("Received a broken close frame containing an invalid size body.");
+ failAsError("Received a broken close frame containing an invalid size body.");
return false;
} else {
unsigned char highByte = static_cast<unsigned char>(frame.payload[0]);
@@ -663,7 +680,7 @@ bool MainThreadWebSocketChannel::processFrame()
m_closeEventCode = highByte << 8 | lowByte;
if (m_closeEventCode == CloseEventCodeNoStatusRcvd || m_closeEventCode == CloseEventCodeAbnormalClosure || m_closeEventCode == CloseEventCodeTLSHandshake) {
m_closeEventCode = CloseEventCodeAbnormalClosure;
- fail("Received a broken close frame containing a reserved status code.");
+ failAsError("Received a broken close frame containing a reserved status code.");
return false;
}
}
@@ -744,13 +761,13 @@ void MainThreadWebSocketChannel::processOutgoingFrameQueue()
switch (frame->frameType) {
case QueuedFrameTypeString: {
if (!sendFrame(frame->opCode, frame->stringData.data(), frame->stringData.length()))
- fail("Failed to send WebSocket frame.");
+ failAsError("Failed to send WebSocket frame.");
break;
}
case QueuedFrameTypeVector:
if (!sendFrame(frame->opCode, frame->vectorData.data(), frame->vectorData.size()))
- fail("Failed to send WebSocket frame.");
+ failAsError("Failed to send WebSocket frame.");
break;
case QueuedFrameTypeBlob: {
@@ -774,7 +791,7 @@ void MainThreadWebSocketChannel::processOutgoingFrameQueue()
m_blobLoader.clear();
m_blobLoaderStatus = BlobLoaderNotStarted;
if (!sendFrame(frame->opCode, static_cast<const char*>(result->data()), result->byteLength()))
- fail("Failed to send WebSocket frame.");
+ failAsError("Failed to send WebSocket frame.");
break;
}
}
@@ -814,12 +831,12 @@ bool MainThreadWebSocketChannel::sendFrame(WebSocketFrame::OpCode opCode, const
OwnPtr<DeflateResultHolder> deflateResult = m_deflateFramer.deflate(frame);
if (!deflateResult->succeeded()) {
- fail(deflateResult->failureReason());
+ failAsError(deflateResult->failureReason());
return false;
}
if (!m_perMessageDeflate.deflate(frame)) {
- fail(m_perMessageDeflate.failureReason());
+ failAsError(m_perMessageDeflate.failureReason());
return false;
}
« no previous file with comments | « Source/modules/websockets/MainThreadWebSocketChannel.h ('k') | Source/modules/websockets/WebSocket.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698