Bug 195059 - Web Inspector: Canvas: protocol error on first open
Summary: Web Inspector: Canvas: protocol error on first open
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Web Inspector (show other bugs)
Version: WebKit Nightly Build
Hardware: All All
: P2 Normal
Assignee: Devin Rousso
URL:
Keywords: InRadar
Depends on: 195058
Blocks:
  Show dependency treegraph
 
Reported: 2019-02-26 11:28 PST by Devin Rousso
Modified: 2019-03-04 12:36 PST (History)
5 users (show)

See Also:


Attachments
Patch (2.26 KB, patch)
2019-02-26 11:34 PST, Devin Rousso
no flags Details | Formatted Diff | Diff
Patch (3.16 KB, patch)
2019-02-26 13:33 PST, Devin Rousso
no flags Details | Formatted Diff | Diff
Patch (3.10 KB, patch)
2019-03-02 12:16 PST, Devin Rousso
no flags Details | Formatted Diff | Diff
Patch (3.05 KB, patch)
2019-03-04 12:09 PST, Devin Rousso
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Devin Rousso 2019-02-26 11:28:01 PST
# STEPS TO REPRODUCE:
1. inspect any page
2. go to the Canvas tab
3. enable auto-capture
4. close Web Inspector
5. open Web Inspector
 => error in inspector2

[Error] Request with id = 2 failed. {"code":-32601,"message":"'Canvas' domain was not found","data":[{"code":-32601,"message":"'Canvas' domain was not found"}]}
	_dispatchResponse (Main.js:1246)
	dispatch (Main.js:1236)
	dispatch (Main.js:1154)
	dispatchNextQueuedMessageFromBackend (Main.js:1329)
[Error] Error: 'Canvas' domain was not found
	(anonymous function) (Main.js:24966:243)
	promiseReactionJob
Comment 1 Radar WebKit Bug Importer 2019-02-26 11:28:43 PST
<rdar://problem/48407871>
Comment 2 Devin Rousso 2019-02-26 11:34:53 PST
Created attachment 362996 [details]
Patch
Comment 3 Joseph Pecoraro 2019-02-26 11:53:01 PST
Comment on attachment 362996 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=362996&action=review

> Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js:104
> +        try {
> +            await CanvasAgent.setRecordingAutoCaptureFrameCount(enabled ? count : 0);

I don't think this is the right approach.

1. initializeTarget should set this state on the target's CanvasAgent.

    initializeTarget(target)
    {
        if (target.CanvasAgent) {
            target.CanvasAgent.enable();
            target.CanvasAgent.setRecordingAutoCaptureFrameCount(<value>);
        }
    }

2. This should update the value and then update the value across all targets with CanvasAgent:

    for (let target of WI.targets) {
        if (target.CanvasAgent)
            target.CanvasAgent.setRecordingAutoCaptureFrameCount(<value>);
    }

That will make this code sufficiently safe for multi-targets.

> Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js:110
> +        } catch (e) {
> +            console.error(e);
> +        }

Would the try/catch be needed at all? Seems it would mask the nicer unhandledrejection display that helps us catch these!
Comment 4 Devin Rousso 2019-02-26 13:33:00 PST
Created attachment 363015 [details]
Patch
Comment 5 Joseph Pecoraro 2019-03-02 01:30:28 PST
Comment on attachment 363015 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=363015&action=review

> Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js:46
> -        if (target.CanvasAgent)
> -            target.CanvasAgent.enable();
> +        if (!target.CanvasAgent)
> +            return;

The style in all of these initializeTargets is:

    if (target.FooAgent) {
        ...
    }

I'd prefer we keep that style consistent for now. Maybe we can convert most of these to early returns later.

> Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js:106
> +        if (!WI.targetsAvailable())
> +            await WI.whenTargetsAvailable();

This part should be unnecessary. When new targets become available the state will be set on them in initializeTarget, so we should not have to wait for them.

> Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js:113
> +                promises.push(target.CanvasAgent.setRecordingAutoCaptureFrameCount(enabled ? count : 0));
> +        }
> +        await Promise.all(promises);

Why do we await these at all? Even if a backend error happened, would we care?

I'd expect this to just be the simple loop and updating the settings:

    for (let target of WI.targets) {
        if (target.CanvasAgent)
            promises.push(target.CanvasAgent.setRecordingAutoCaptureFrameCount(enabled ? count : 0));
    }

    WI.settings.canvasRecordingAutoCaptureEnabled.value = enabled && count;
    WI.settings.canvasRecordingAutoCaptureFrameCount.value = count;
Comment 6 Devin Rousso 2019-03-02 12:14:47 PST
Comment on attachment 363015 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=363015&action=review

>> Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js:106
>> +            await WI.whenTargetsAvailable();
> 
> This part should be unnecessary. When new targets become available the state will be set on them in initializeTarget, so we should not have to wait for them.

Good point!

>> Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js:113
>> +        await Promise.all(promises);
> 
> Why do we await these at all? Even if a backend error happened, would we care?
> 
> I'd expect this to just be the simple loop and updating the settings:
> 
>     for (let target of WI.targets) {
>         if (target.CanvasAgent)
>             promises.push(target.CanvasAgent.setRecordingAutoCaptureFrameCount(enabled ? count : 0));
>     }
> 
>     WI.settings.canvasRecordingAutoCaptureEnabled.value = enabled && count;
>     WI.settings.canvasRecordingAutoCaptureFrameCount.value = count;

I prefer avoid changing values in the frontend until we know that it actually "worked" in the backend, as this can help prevent data corruption (e.g. somehow passing a string as `count` instead of a number would "corrupt" the setting's value to be a string).

What I wrote doesn't do anything in the case of an error, so that would be thrown (and caught by the global error handler) as expected.
Comment 7 Devin Rousso 2019-03-02 12:16:57 PST
Created attachment 363426 [details]
Patch
Comment 8 Joseph Pecoraro 2019-03-04 11:59:44 PST
Comment on attachment 363426 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=363426&action=review

r=me

> Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js:104
> +        if (WI.targetsAvailable()) {

Is this necessary? When no targets are available, WI.targets should be an empty list safe to iterate.
Comment 9 Devin Rousso 2019-03-04 12:04:20 PST
Comment on attachment 363426 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=363426&action=review

>> Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js:104
>> +        if (WI.targetsAvailable()) {
> 
> Is this necessary? When no targets are available, WI.targets should be an empty list safe to iterate.

🤦‍♂️
Comment 10 Devin Rousso 2019-03-04 12:09:41 PST
Created attachment 363538 [details]
Patch
Comment 11 WebKit Commit Bot 2019-03-04 12:35:59 PST
Comment on attachment 363538 [details]
Patch

Clearing flags on attachment: 363538

Committed r242374: <https://trac.webkit.org/changeset/242374>
Comment 12 WebKit Commit Bot 2019-03-04 12:36:01 PST
All reviewed patches have been landed.  Closing bug.