Title: [202875] trunk/Source/WebInspectorUI
Revision
202875
Author
[email protected]
Date
2016-07-06 13:22:46 -0700 (Wed, 06 Jul 2016)

Log Message

Web Inspector: Uncaught Exception reporter should include the currently dispatching protocol event or request/response if applicable
https://bugs.webkit.org/show_bug.cgi?id=159320
<rdar://problem/27117754>

Reviewed by Timothy Hatcher and Joseph Pecoraro.

Keep track of the currently dispatched protocol response or protocol event and make
them available to the uncaught exception reporter. If an internal exception is reported
while dispatching an event or response, dump the protocol message(s) into the pre-filled
bug report.

* UserInterface/Debug/UncaughtExceptionReporter.js:
(stringifyAndTruncateObject): Added.
Rearrange the code that generates the pre-filled report so it's easier to add optional sections.

* UserInterface/Protocol/InspectorBackend.js:
(InspectorBackendClass):
(InspectorBackendClass.prototype.get currentDispatchState): Expose the dispatching state.
(InspectorBackendClass.prototype._sendCommandToBackendWithCallback):
(InspectorBackendClass.prototype._sendCommandToBackendExpectingPromise):
Store the originating command request with the pendingResponse data so that we can examine
the originating request if the response causes an error. This will cause request message objects
to be garbage-collected after their responses are dispatched rather than when the request is sent.
But, I don't forsee this being a performance problem since we should always get a command response
and pending command responses do not typically accumulate except when the inspector first loads.

(InspectorBackendClass.prototype._dispatchResponse): Save the response being dispatched.
(InspectorBackendClass.prototype._dispatchResponseToCallback): Simplify exception reporting.
(InspectorBackendClass.prototype._dispatchEvent): Save the event being dispatched.

Modified Paths

Diff

Modified: trunk/Source/WebInspectorUI/ChangeLog (202874 => 202875)


--- trunk/Source/WebInspectorUI/ChangeLog	2016-07-06 20:14:38 UTC (rev 202874)
+++ trunk/Source/WebInspectorUI/ChangeLog	2016-07-06 20:22:46 UTC (rev 202875)
@@ -1,3 +1,35 @@
+2016-07-06  Brian Burg  <[email protected]>
+
+        Web Inspector: Uncaught Exception reporter should include the currently dispatching protocol event or request/response if applicable
+        https://bugs.webkit.org/show_bug.cgi?id=159320
+        <rdar://problem/27117754>
+
+        Reviewed by Timothy Hatcher and Joseph Pecoraro.
+
+        Keep track of the currently dispatched protocol response or protocol event and make
+        them available to the uncaught exception reporter. If an internal exception is reported
+        while dispatching an event or response, dump the protocol message(s) into the pre-filled
+        bug report.
+
+        * UserInterface/Debug/UncaughtExceptionReporter.js:
+        (stringifyAndTruncateObject): Added.
+        Rearrange the code that generates the pre-filled report so it's easier to add optional sections.
+
+        * UserInterface/Protocol/InspectorBackend.js:
+        (InspectorBackendClass):
+        (InspectorBackendClass.prototype.get currentDispatchState): Expose the dispatching state.
+        (InspectorBackendClass.prototype._sendCommandToBackendWithCallback):
+        (InspectorBackendClass.prototype._sendCommandToBackendExpectingPromise):
+        Store the originating command request with the pendingResponse data so that we can examine
+        the originating request if the response causes an error. This will cause request message objects
+        to be garbage-collected after their responses are dispatched rather than when the request is sent.
+        But, I don't forsee this being a performance problem since we should always get a command response
+        and pending command responses do not typically accumulate except when the inspector first loads.
+
+        (InspectorBackendClass.prototype._dispatchResponse): Save the response being dispatched.
+        (InspectorBackendClass.prototype._dispatchResponseToCallback): Simplify exception reporting.
+        (InspectorBackendClass.prototype._dispatchEvent): Save the event being dispatched.
+
 2016-07-05  Timothy Hatcher  <[email protected]>
 
         Web Inspector: Switch last uses of -webkit-linear-gradient() to linear-gradient()

Modified: trunk/Source/WebInspectorUI/UserInterface/Debug/UncaughtExceptionReporter.js (202874 => 202875)


--- trunk/Source/WebInspectorUI/UserInterface/Debug/UncaughtExceptionReporter.js	2016-07-06 20:14:38 UTC (rev 202874)
+++ trunk/Source/WebInspectorUI/UserInterface/Debug/UncaughtExceptionReporter.js	2016-07-06 20:22:46 UTC (rev 202875)
@@ -181,16 +181,46 @@
         inspectedPageURL = WebInspector.frameResourceManager.mainFrame.url;
     } catch (e) { }
 
+    let topLevelItems = [
+        `Inspected URL:        ${inspectedPageURL || "(unknown)"}`,
+        `Loading completed:    ${!!loadCompleted}`,
+        `Frontend User Agent:  ${window.navigator.userAgent}`,
+    ];
+
+    function stringifyAndTruncateObject(object) {
+        let string = JSON.stringify(object);
+        return string.length > 500 ? string.substr(0, 500) + "…" : string;
+    }
+
+    if (InspectorBackend && InspectorBackend.currentDispatchState) {
+        let state = InspectorBackend.currentDispatchState;
+        if (state.event) {
+            topLevelItems.push("Dispatch Source:      Protocol Event");
+            topLevelItems.push("");
+            topLevelItems.push("Protocol Event:");
+            topLevelItems.push(stringifyAndTruncateObject(state.event));
+        }
+        if (state.response) {
+            topLevelItems.push("Dispatch Source:      Protocol Command Response");
+            topLevelItems.push("");
+            topLevelItems.push("Protocol Command Response:");
+            topLevelItems.push(stringifyAndTruncateObject(state.response));
+        }
+        if (state.request) {
+            topLevelItems.push("");
+            topLevelItems.push("Protocol Command Request:");
+            topLevelItems.push(stringifyAndTruncateObject(state.request));
+        }
+    }
+
     let formattedErrorDetails = window.__uncaughtExceptions.map((entry) => formattedEntry(entry));
     let detailsForBugReport = formattedErrorDetails.map((line) => ` - ${line}`).join("\n");
+    topLevelItems.push("");
+    topLevelItems.push("Uncaught Exceptions:");
+    topLevelItems.push(detailsForBugReport);
+
     let encodedBugDescription = encodeURIComponent(`-------
-Auto-generated details:
-
-Inspected URL:        ${inspectedPageURL || "(unknown)"}
-Loading completed:    ${!!loadCompleted}
-Frontend User Agent:  ${window.navigator.userAgent}
-Uncaught exceptions:
-${detailsForBugReport}
+${topLevelItems.join("\n")}
 -------
 
 * STEPS TO REPRODUCE

Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js (202874 => 202875)


--- trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js	2016-07-06 20:14:38 UTC (rev 202874)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js	2016-07-06 20:22:46 UTC (rev 202875)
@@ -43,6 +43,12 @@
         this._defaultTracer = new WebInspector.LoggingProtocolTracer;
         this._activeTracers = [this._defaultTracer];
 
+        this._currentDispatchState = {
+            event: null,
+            request: null,
+            response: null,
+        };
+
         this._dumpInspectorTimeStats = false;
 
         let setting = WebInspector.autoLogProtocolMessagesSetting = new WebInspector.Setting("auto-collect-protocol-messages", false);
@@ -205,7 +211,7 @@
         if (!isEmptyObject(parameters))
             messageObject["params"] = parameters;
 
-        let responseData = {command, callback};
+        let responseData = {command, request: messageObject, callback};
 
         if (this.activeTracer)
             responseData.sendRequestTimestamp = timestamp();
@@ -226,7 +232,7 @@
         if (!isEmptyObject(parameters))
             messageObject["params"] = parameters;
 
-        let responseData = {command};
+        let responseData = {command, request: messageObject};
 
         if (this.activeTracer)
             responseData.sendRequestTimestamp = timestamp();
@@ -262,19 +268,25 @@
         console.assert(this._pendingResponses.has(sequenceId), sequenceId, this._pendingResponses);
 
         let responseData = this._pendingResponses.take(sequenceId) || {};
-        let {command, callback, promise} = responseData;
+        let {request, command, callback, promise} = responseData;
 
         let processingStartTimestamp = timestamp();
         for (let tracer of this.activeTracers)
             tracer.logWillHandleResponse(messageObject);
 
+        this._currentDispatchState.request = request;
+        this._currentDispatchState.response = messageObject;
+
         if (typeof callback === "function")
-            this._dispatchResponseToCallback(command, messageObject, callback);
+            this._dispatchResponseToCallback(command, request, messageObject, callback);
         else if (typeof promise === "object")
             this._dispatchResponseToPromise(command, messageObject, promise);
         else
             console.error("Received a command response without a corresponding callback or promise.", messageObject, command);
 
+        this._currentDispatchState.request = null;
+        this._currentDispatchState.response = null;
+
         let processingTime = (timestamp() - processingStartTimestamp).toFixed(3);
         let roundTripTime = (processingStartTimestamp - responseData.sendRequestTimestamp).toFixed(3);
 
@@ -285,23 +297,20 @@
             this._flushPendingScripts();
     }
 
-    _dispatchResponseToCallback(command, messageObject, callback)
+    _dispatchResponseToCallback(command, requestObject, responseObject, callback)
     {
         let callbackArguments = [];
-        callbackArguments.push(messageObject["error"] ? messageObject["error"].message : null);
+        callbackArguments.push(responseObject["error"] ? responseObject["error"].message : null);
 
-        if (messageObject["result"]) {
-            for (var parameterName of command.replySignature)
-                callbackArguments.push(messageObject["result"][parameterName]);
+        if (responseObject["result"]) {
+            for (let parameterName of command.replySignature)
+                callbackArguments.push(responseObject["result"][parameterName]);
         }
 
         try {
             callback.apply(null, callbackArguments);
         } catch (e) {
-            WebInspector.reportInternalError(e, {
-                "cause": `An uncaught exception was thrown while dispatching response callback for command ${command.qualifiedName}.`,
-                "protocol-message": JSON.stringify(messageObject),
-            });
+            WebInspector.reportInternalError(e, {"cause": `An uncaught exception was thrown while dispatching response callback for command ${command.qualifiedName}.`});
         }
     }
 
@@ -343,6 +352,8 @@
         for (let tracer of this.activeTracers)
             tracer.logWillHandleEvent(messageObject);
 
+        this._currentDispatchState.event = messageObject;
+
         try {
             agent.dispatchEvent(eventName, eventArguments);
         } catch (e) {
@@ -349,12 +360,11 @@
             for (let tracer of this.activeTracers)
                 tracer.logFrontendException(messageObject, e);
 
-            WebInspector.reportInternalError(e, {
-                "cause": `An uncaught exception was thrown while handling event: ${qualifiedName}`,
-                "protocol-message": JSON.stringify(messageObject),
-            });
+            WebInspector.reportInternalError(e, {"cause": `An uncaught exception was thrown while handling event: ${qualifiedName}`});
         }
 
+        this._currentDispatchState.event = null;
+
         let processingDuration = (timestamp() - processingStartTimestamp).toFixed(3);
         for (let tracer of this.activeTracers)
             tracer.logDidHandleEvent(messageObject, {dispatch: processingDuration});
@@ -400,6 +410,8 @@
         return this._active;
     }
 
+    get currentDispatchState() { return this._currentDispatchState; }
+
     set dispatcher(value)
     {
         this._dispatcher = value;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to