Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS errors sent from the iframe to the parent context aren't serialised correctly #10

Closed
thomas-r7 opened this issue Jan 3, 2019 · 2 comments

Comments

@thomas-r7
Copy link

The callback of window.onerror is as follows:

window.onerror = function(message, source, lineno, colno, error) { ... }

The last parameter 'error' is an Error instance. When this error is caught and sent to the context (via the reverse context), postMessage is used but Error objects can't be serialised in postMessage and so the call fails and the error never makes it to the parent context. The error thrown in this case looks like:
Uncaught DOMException: Failed to execute 'postMessage' on 'Window': Error could not be cloned.

This seems to specifically be for errors in the JS document itself (syntax errors etc) rather than asserts in the tests themselves.

The offending code is in reverse-context.js, lines 30-36:

DIRECT_METHODS = ['error', 'log', 'complete', 'result'];
DIRECT_METHODS.forEach(method => {
	karma[method] = function() {
		callParentKarmaMethod(method, Array.prototype.slice.call(arguments));
	}
	karma[method].displayName = method+' (proxied)';
});

This could be corrected by adding a transform to the arguments array that converts Error objects into strings, e.g.

DIRECT_METHODS = ['error', 'log', 'complete', 'result'];
DIRECT_METHODS.forEach(method => {
	karma[method] = function() {
		var args = Array.prototype.slice.call(arguments);
		for (var i = 0, l = args.length; i < l; ++i) {
			if (args[i] instanceof Error) {
				args[i] = args[i].stack || args[i].toString();
			}
		}
		callParentKarmaMethod(method, args);
	}
	karma[method].displayName = method+' (proxied)';
});

This does mean however that karma never sees an Error object on the other end, only a string, but it gets sent right to karma.error so this might be ok.

@sabberworm
Copy link
Owner

Thanks a lot for investigating this and for the suggested fix.

I’d put the sanitization code directly in callParentKarmaMethod but otherwise I like this fix.

Maybe we could use an object that contains all the properties of the original error instead of simply using the stack or toString.

And the messageListener in iframes-adapter could then again make an error out of this object…

Could you test that for me and open a pull-request?

@sabberworm
Copy link
Owner

Released with 1.2.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants