Skip to content
This repository was archived by the owner on Jan 30, 2025. It is now read-only.

Conversation

imiric
Copy link
Contributor

@imiric imiric commented Nov 22, 2021

Previously we used to throw an error if we encountered a custom object as returned by CDP from an Evaluate() or console.log() call.

This should handle those cases properly now by converting objects to map[string]interface{} internally, and using a custom Logrus formatter to marshall the map to JSON for safe output when used with console.log().

Fixes #120

Copy link
Collaborator

@robingustafsson robingustafsson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just one minor nitpick. Nice to finally get rid of this error!

Copy link
Collaborator

@inancgumus inancgumus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job! 👏

Overall is good. Maybe we can untangle Logrus from the code to prevent Logrus to propagate into the system much more. I think it's better to separate logging responsibility from parsing.

For example, we don't need to check for: "object will be parsed partially" in parseRemoteObjectPreview using a logger which complicates tests and tangles logging with parsing.

Instead, we can test whether parseRemoteObjectValue returns these error messages, and test against that, and use them in the frame session, here is a rough idea:

func parseRemoteObjectPreview(op *cdpruntime.ObjectPreview) (map[string]interface{}, error) {
	var errs error
	
	if op.Overflow {
		errs = multierror.Append(errs, errors.New("object will be parsed partially"))
	}
	
	obj := make(map[string]interface{})
	for _, p := range op.Properties {
		val, err := parseRemoteObjectValue(p.Type, p.Value, p.ValuePreview)
		if err != nil {
			errs = multierror.Append(errs, fmt.Errorf("failed parsing object property '%s'", p.Name))
			continue
		}
		obj[p.Name] = val
	}
	return obj, errs
}

Then in frame_session:

func (fs *FrameSession) onConsoleAPICalled(event *runtime.EventConsoleAPICalled) {
	...
	for _, robj := range event.Args {
		i, err := parseRemoteObject(robj, l)
		if err == nil {
			parsedObjects = append(parsedObjects, i)
			continue
		}
		if merr, ok := err.(*multierror.Error); ok {
			// check if partial parse
			// log here

			// check if "failed parsing object property"
			// log here
			continue
		}
		// If this throws it's a bug :)
		k6Throw(fs.ctx, "unable to parse remote object value: %w", err)
	}
        ...

Then in tests, you can check against these errors without using a logger.

Btw, can you also convert every k6common.Throw to k6Throw while in here?
So we can make this code into a proper shape :)

imiric pushed a commit that referenced this pull request Nov 26, 2021
imiric pushed a commit that referenced this pull request Nov 26, 2021
imiric pushed a commit that referenced this pull request Nov 26, 2021
@imiric imiric force-pushed the fix/120-panic-page-goto branch from ee3a495 to 47a91dc Compare November 26, 2021 11:21
@imiric imiric force-pushed the fix/120-panic-page-goto branch from 47a91dc to 7c2eaae Compare November 26, 2021 11:37
@imiric
Copy link
Contributor Author

imiric commented Nov 26, 2021

@inancgumus re: using multierror and asserting on an error instead of a log message:

  • I'm not a fan of multierror in this case since this is really a warning, not an error. Something like warnings might make more sense, though not sure if we should rely on that.

  • I really want to check that the event was logged and will be shown to the user, but you're right that low-level "helper" functions like this probably shouldn't log, and allow the event to be handled higher up. Relying on logging assertions is always brittle, and we should do that only in higher-level integration or E2E tests, of which there should be less anyway.

If you agree, I can rewrite it with warnings instead and remove the logging. Let me know.

@inancgumus
Copy link
Collaborator

inancgumus commented Nov 26, 2021

@inancgumus re: using multierror and asserting on an error instead of a log message:

Can I ask why?

Errors and asserting on errors are the standard way of working in Go. The whole stdlib works like that. Even errors.As and errors.Is added for that to the stdlib (we can also use these btw instead of multierror).

So, we don't have to use the multierror package. We can do what I suggested with a couple of lines ourselves if we want (or copy it from multierror).

  • I'm not a fan of multierror in this case since this is really a warning, not an error. Something like warnings might make more sense, though not sure if we should rely on that.

I think not everything should be an error to be handled as an error. For example, io.EOF is not an error but a signal. Our situation is similar.

So far from what I see, I don't like the API of the warnings package because it forces us to use the Collect methods and create a Collector, kinda loaded.

  • I really want to check that the event was logged and will be shown to the user, but you're right that low-level "helper" functions like this probably shouldn't log, and allow the event to be handled higher up. Relying on logging assertions is always brittle, and we should do that only in higher-level integration or E2E tests, of which there should be less anyway.

👍

If you agree, I can rewrite it with warnings instead and remove the logging. Let me know.

I'm trying to convince you that we can use simple errors instead of depending on that package but your call.

@imiric
Copy link
Contributor Author

imiric commented Nov 26, 2021

OK, I'll change it to a custom error or use multierror on Monday.

imiric pushed a commit that referenced this pull request Nov 29, 2021
imiric pushed a commit that referenced this pull request Nov 29, 2021
@imiric imiric requested a review from inancgumus November 29, 2021 13:53
Ivan Mirić added 7 commits November 30, 2021 10:44
Previously we used to throw an error if we encountered a custom object
as returned by CDP from an `Evaluate()` or `console.log()` call.

This should handle those cases properly now by converting objects to
`map[string]interface{}` internally, and using a custom Logrus formatter
to marshall the map to JSON for safe output when used with `console.log()`.

Fixes #120
imiric pushed a commit that referenced this pull request Nov 30, 2021
@imiric imiric force-pushed the fix/120-panic-page-goto branch from 3a4f461 to 7a5de2f Compare November 30, 2021 11:08
@imiric imiric requested a review from inancgumus November 30, 2021 11:14
imiric pushed a commit that referenced this pull request Nov 30, 2021
@imiric imiric force-pushed the fix/120-panic-page-goto branch from 7a5de2f to 886b852 Compare November 30, 2021 12:07
imiric pushed a commit that referenced this pull request Nov 30, 2021
@imiric imiric force-pushed the fix/120-panic-page-goto branch from 886b852 to a6d9371 Compare November 30, 2021 12:27
Copy link
Collaborator

@inancgumus inancgumus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍 I added my suggestions.

Btw, let's call t.Parallel in each t.Run. I tested it out, and it works.

Copy link
Collaborator

@inancgumus inancgumus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT?

@imiric imiric force-pushed the fix/120-panic-page-goto branch from a6d9371 to 152b56d Compare November 30, 2021 14:07
@imiric imiric requested a review from inancgumus November 30, 2021 14:11
Copy link
Collaborator

@inancgumus inancgumus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

@imiric imiric merged commit 3aca99a into main Nov 30, 2021
@imiric imiric deleted the fix/120-panic-page-goto branch November 30, 2021 15:53
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Page.goto() Unable to load page

3 participants