-
Notifications
You must be signed in to change notification settings - Fork 27.4k
fix(minErr/ngRepeat/$rootScope): serialization of error objects #10085
Conversation
2331e4d
to
49d3b50
Compare
The circular reference detection scheme does not look right, you'd need to do a depth-first traversal of object properties and return them as strings to make that work. It's also not really a cheap operation, so we probably don't want to do that during interpolation. |
I agree that it is not a real circular reference scheme. It is a basic algorithm that will get us a half decent error message. |
You're right, $interpolate has its own |
rename which one :-) ? |
How about this new method is called |
Actually the |
Fix the JSON stringification to output a more meaningful string when an object cannot be normally converted to a JSON string, such as when the object contains cyclic references that would cause `JSON.stringify()` to throw an error.
Now that `minErr` can cope with objects that cannot be normally stringified to JSON, just pass the error arguments straight through without trying to stringify them first. Closes angular#9838 Closes angular#10065
…or messages Use the new private function `stringify` to convert scope values to strings, since this can cope with cyclic references and other oddities.
49d3b50
to
587dcc3
Compare
I fixed up the |
I guess it looks fine, I like the idea to separate toJson and toDebugString. function decycleObject(object, seen) {
if (isObject(object)) {
var safeObject = {};
// make local copy of the reference array to be sure
// objects are referenced in straight line
seen = seen ? seen.slice() : [];
for (var key in object) {
var property = object[key];
if (isObject(property)) {
if (seen.indexOf(property) >= 0) {
safeObject[key] = '<<already seen>>';
} else {
if(seen.indexOf(object) === -1) seen.push(object);
safeObject[key] = decycleObject(property, seen)
}
} else {
safeObject[key] = property;
}
}
return safeObject;
}
return object;
} You can see diffirence that it produce compared to your function in this plunkr. What do you think? |
Actually, I would also change |
Thanks @kwypchlo. I appreciate that it feels like I pulled the rug out from under you on this one. Sorry about that but it was as easy to implement it than to describe it. How about we merge this and then you can provide PRs to make the changes you suggest? We probably should go with something like |
Or we could even just change it to |
The only other thing about the algorithm is that we don't want to add too many more bytes to the download. |
Interestingly this PR actually knocks a little bit off the gzipped angular.min.js file (44.47Kb over 44.49Kb) |
@petebacondarwin don't worry about it :) I love angular and it feels good to help out anyhow 👍 Just go ahead with your PR and if you feel that the decycle function is worth the bytes, I can add it in in separate PR with tests. Also I guess |
…or messages Use the new private function `stringify` to convert scope values to strings, since this can cope with cyclic references and other oddities. Closes #10085
As discussed in angular#10085 this commit adds a function for replacing cycle references in object. It is recursive and it knows if the reference has been made in a straight lin e (sibling objects will be left but object referencing same object will be replaced). It also changes the replacement string to '...' because the older one could be mistaken for html tag by browsers.
As discussed in angular#10085 this commit adds a function for replacing cycle references in object. It is recursive and it knows if the reference has been made in a straight lin e (sibling objects will be left but object referencing same object will be replaced). It also changes the replacement string to '...' because the older one could be mistaken for html tag by browsers.
As discussed in angular#10085 this commit adds a function for replacing cycle references in object. It is recursive and it knows if the reference has been made in a straight lin e (sibling objects will be left but object referencing same object will be replaced). It also changes the replacement string to '...' because the older one could be mistaken for html tag by browsers.
As discussed in angular#10085 this commit adds a function for replacing cycle references in object. It is recursive and it knows if the reference has been made in a straight lin e (sibling objects will be left but object referencing same object will be replaced). It also changes the replacement string to '...' because the older one could be mistaken for html tag by browsers.
As discussed in angular#10085 this commit adds a function for replacing cycle references in object. It is recursive and it knows if the reference has been made in a straight lin e (sibling objects will be left but object referencing same object will be replaced). It also changes the replacement string to '...' because the older one could be mistaken for html tag by browsers.
As discussed in angular#10085, the original replacement string can be treated as html when displayed by the browser so it replaces it with '...' string.
This is my preferred solution to #9838.
toJson
should throw errors on cyclic object references. JSON is not really designed to handle this out of the box and we should not be hiding the error from the developer.Adding a hidden parameter is just making this method convoluted and slowing it down.
Instead we should consider that for error messages, we do not high fidelity serialization of objects but instead a readable string that is useful for debugging. Returning
undefined
for broken JSON stringification is not helpful.This fix provides a new function
stringify
which is available within theangular.js
file and also within theangular-loader.js
file. This function is then used insideminErr
and$rootScope
to provide nice string forms of objects.Places that were using
toJson
to create error messages (i.e.ngRepeat
and$rootScope
) no either pass the object directly tominErr
or they use thestringify
method directly.This solution ensures that we don't confuse the point of
toJson
- it is not a generic stringification tool, it is designed for converting to and from valid JSON. The new methodstringify
also provides us with a single future improvement point if we wished to make the stringification of objects to strings more comprehensive.